Insert more error checks
This commit is contained in:
parent
18392104cd
commit
ef10d11098
1 changed files with 30 additions and 16 deletions
|
@ -43,9 +43,11 @@ class SilicaEngine {
|
||||||
|
|
||||||
var maskContext: CGContext?
|
var maskContext: CGContext?
|
||||||
|
|
||||||
let kernel = getBlendKernel(layer)
|
guard let kernel = getBlendKernel(layer) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if layer.mask != nil {
|
if let mask = layer.mask {
|
||||||
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
||||||
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
||||||
|
|
||||||
|
@ -60,7 +62,7 @@ class SilicaEngine {
|
||||||
maskContext?.setFillColor(.white)
|
maskContext?.setFillColor(.white)
|
||||||
maskContext?.fill(document.cgRect())
|
maskContext?.fill(document.cgRect())
|
||||||
|
|
||||||
for chunk in layer.mask!.chunks {
|
for chunk in mask.chunks {
|
||||||
if let image = chunk.image {
|
if let image = chunk.image {
|
||||||
maskContext?.draw(image, in: document.getChunkRect(chunk))
|
maskContext?.draw(image, in: document.getChunkRect(chunk))
|
||||||
}
|
}
|
||||||
|
@ -72,7 +74,9 @@ class SilicaEngine {
|
||||||
layerContext?.setBlendMode(.normal)
|
layerContext?.setBlendMode(.normal)
|
||||||
|
|
||||||
if !layer.data.hidden {
|
if !layer.data.hidden {
|
||||||
layerContext?.draw(chunk.image!, in: document.getChunkRect(chunk))
|
if let image = chunk.image {
|
||||||
|
layerContext?.draw(image, in: document.getChunkRect(chunk))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +87,10 @@ class SilicaEngine {
|
||||||
var clippedMaster: CGImage? = layerImage
|
var clippedMaster: CGImage? = layerImage
|
||||||
for layer in clippingLayers {
|
for layer in clippingLayers {
|
||||||
// so we if we want to clip, we want to gather all of the clipping layers in order first...
|
// so we if we want to clip, we want to gather all of the clipping layers in order first...
|
||||||
let temporaryClippedMaster = blendLayer(document: document, layer: layer, previousImage: &clippedMaster)
|
if let temporaryClippedMaster = blendLayer(document: document, layer: layer, previousImage: &clippedMaster) {
|
||||||
|
|
||||||
clippedMaster = context.createCGImage(temporaryClippedMaster, from: document.cgRect(), format: .RGBA8, colorSpace: document.colorSpace)
|
clippedMaster = context.createCGImage(temporaryClippedMaster, from: document.cgRect(), format: .RGBA8, colorSpace: document.colorSpace)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
layerContext?.setAlpha(1.0)
|
layerContext?.setAlpha(1.0)
|
||||||
layerContext?.setBlendMode(.sourceAtop)
|
layerContext?.setBlendMode(.sourceAtop)
|
||||||
|
@ -106,7 +110,9 @@ class SilicaEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply image
|
// apply image
|
||||||
masterImage = kernel!.apply(foreground: CIImage(cgImage: previousImage!), background: masterImage, colorSpace: document.colorSpace)!
|
masterImage = kernel.apply(foreground: CIImage(cgImage: previousImage!),
|
||||||
|
background: masterImage,
|
||||||
|
colorSpace: document.colorSpace)!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +122,7 @@ class SilicaEngine {
|
||||||
func makeBlendImage(document: SilicaDocument, layer: SilicaLayer) -> CGImage {
|
func makeBlendImage(document: SilicaDocument, layer: SilicaLayer) -> CGImage {
|
||||||
var maskContext: CGContext?
|
var maskContext: CGContext?
|
||||||
|
|
||||||
if layer.mask != nil {
|
if let mask = layer.mask {
|
||||||
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
||||||
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
||||||
|
|
||||||
|
@ -131,8 +137,10 @@ class SilicaEngine {
|
||||||
maskContext?.setFillColor(.white)
|
maskContext?.setFillColor(.white)
|
||||||
maskContext?.fill(document.cgRect())
|
maskContext?.fill(document.cgRect())
|
||||||
|
|
||||||
for chunk in layer.mask!.chunks {
|
for chunk in mask.chunks {
|
||||||
maskContext?.draw(chunk.image!, in: document.getChunkRect(chunk))
|
if let image = chunk.image {
|
||||||
|
maskContext?.draw(image, in: document.getChunkRect(chunk))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +169,9 @@ class SilicaEngine {
|
||||||
layerContext?.setBlendMode(.normal)
|
layerContext?.setBlendMode(.normal)
|
||||||
|
|
||||||
if !layer.hidden {
|
if !layer.hidden {
|
||||||
layerContext?.draw(chunk.image!, in: document.getChunkRect(chunk))
|
if let image = chunk.image {
|
||||||
|
layerContext?.draw(image, in: document.getChunkRect(chunk))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +183,7 @@ class SilicaEngine {
|
||||||
/// - layer: The `SilicaLayer` to draw.
|
/// - layer: The `SilicaLayer` to draw.
|
||||||
/// - previousImage: Previous `CGImage` to draw on top of, can be null.
|
/// - previousImage: Previous `CGImage` to draw on top of, can be null.
|
||||||
/// - Returns: A `CIImage` of the new image.
|
/// - Returns: A `CIImage` of the new image.
|
||||||
func blendLayer(document: SilicaDocument, layer : SilicaLayer, previousImage : inout CGImage?) -> CIImage {
|
func blendLayer(document: SilicaDocument, layer : SilicaLayer, previousImage : inout CGImage?) -> CIImage? {
|
||||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big)
|
||||||
|
|
||||||
// start by creating a new layer composite image, needed for image masking
|
// start by creating a new layer composite image, needed for image masking
|
||||||
|
@ -187,21 +197,25 @@ class SilicaEngine {
|
||||||
|
|
||||||
layerContext?.clear(document.cgRect())
|
layerContext?.clear(document.cgRect())
|
||||||
|
|
||||||
let kernel = getBlendKernel(layer)
|
guard let kernel = getBlendKernel(layer) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
for chunk in layer.data.chunks {
|
for chunk in layer.data.chunks {
|
||||||
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
||||||
layerContext?.setBlendMode(.normal)
|
layerContext?.setBlendMode(.normal)
|
||||||
|
|
||||||
if !layer.data.hidden {
|
if !layer.data.hidden {
|
||||||
layerContext?.draw(chunk.image!, in: document.getChunkRect(chunk))
|
if let image = chunk.image {
|
||||||
|
layerContext?.draw(image, in: document.getChunkRect(chunk))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let layerImage = layerContext?.makeImage()
|
let layerImage = layerContext?.makeImage()
|
||||||
|
|
||||||
// apply image
|
// apply image
|
||||||
return kernel!.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: document.colorSpace)!
|
return kernel.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: document.colorSpace)!
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Figures out the correct `CIBlendKernel` corresponding to the `SilicaLayer`'s blending mode.
|
/// Figures out the correct `CIBlendKernel` corresponding to the `SilicaLayer`'s blending mode.
|
||||||
|
|
Reference in a new issue