SlideShare a Scribd company logo
Kyome
macOS native symposium #06

2019/12/21
Takuto Nakamura
@Kyomesuke
RunCat TweetShot ScreenPointer Measures
🐈


AppKit
• macOS 

• NSBezierPath
• NSGraphicsContext
•
ref. Apple Inc. "Coordinate system" (2018)
https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/CoordinateSystem.html
iOS macOS
macOS
• Core Graphics
- CGPath (CGMutablePath)
- CGContext
• AppKit
- NSBezierPath
- NSGraphicsContext
• Core Graphics
- CGPath (CGMutablePath)
- CGContext
• AppKit
- NSBezierPath
- NSGraphicsContext
😖
• Core Graphics
- CGPath (CGMutablePath)
- CGContext
• AppKit
- NSBezierPath
- NSGraphicsContext
🤔
• CGPath (CGMutablePath)




• CGContext


💪
• NSBezierPath


• NSGraphicsContext




😊
• Core Graphics
- CGPath (CGMutablePath)
- CGContext
• AppKit
- NSBezierPath
- NSGraphicsContext
P0
P1
P2
P3
class CustomView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let path = NSBezierPath()
path.move(to: NSPoint(x: 10, y: 10))
path.line(to: NSPoint(x: 150, y: 120))
path.curve(to: NSPoint(x: 240, y: 10),
controlPoint1: NSPoint(x: 225, y: 180),
controlPoint2: NSPoint(x: 240, y: 165))
path.close()
path.stroke()
}
}
class CustomView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
}
let path = NSBezierPath()
path.move(to: NSPoint(x: 10, y: 10))
→
path.line(to: NSPoint(x: 150, y: 120))
→
path.curve(to: NSPoint(x: 240, y: 10),
controlPoint1: NSPoint(x: 225, y: 180),
controlPoint2: NSPoint(x: 240, y: 165))
→
path.close()
path.stroke() //
path.fill() //
→
• 2 4 

•
⚠
P0
P1
P2
P3P0
P1
//
path.appendRect(rect:)
//
path.appendOval(in:)
//
path.appendRoundedRect(rect:, xRadius:, yRadius:)
//
path.appendArc(from:, to:, radius:)
path.appendArc(withCenter:, radius:, startAngle:, endAngle:)
path.relativeMove(to: NSPoint.zero)
path.relativeLine(to: NSPoint.zero)
path.relativeCurve(to: NSPoint.zero,
controlPoint1: NSPoint.zero,
controlPoint2: NSPoint.zero)
※
let face = NSBezierPath(ovalIn: NSRect(x: 60, y: 40,
width: 80, height: 80))
let earL = NSBezierPath(ovalIn: NSRect(x: 50, y: 105,
width: 40, height: 40))
let earR = NSBezierPath(ovalIn: NSRect(x: 110, y: 105,
width: 40, height: 40))
//
face.append(earL)
face.append(earR)
face.fill()
//
path.lineWidth = 3
//
path.lineCapStyle = .round
//
path.lineJoinStyle = .bevel
//
path.miterLimit = 5
//
path.setLineDash([8.0, 12.0], count: 2, phase: 0)
extension NSBezierPath {
func printPathElement() {
var points = [CGPoint](repeating: CGPoint.zero, count: 3)
for i in (0 ..< self.elementCount) {
switch self.element(at: i, associatedPoints: &points) {
case .moveTo:
print("move:", points[0])
case .lineTo:
print("line to:", points[0])
case .curveTo:
print("curve to:", points[2])
print("controlPoint1:", points[0])
print("controlPoint2:", points[1])
case.closePath:
print("close")
@unknown default:
fatalError()
}
}
}
}


→ move 



↙
let path = NSBezierPath()
path.appendRect(NSRect(x: 10, y: 10, width: 190, height: 150))
path.appendOval(in: NSRect(x: 40, y: 30, width: 70, height: 60))
NSColor.red.setFill()
path.fill()
let path = NSBezierPath()
path.appendRect(NSRect(x: 10, y: 10, width: 190, height: 150))
let ellipse = NSBezierPath()
ellipse.appendOval(in: NSRect(x: 50, y: 50, width: 80, height: 70))
//
path.append(ellipse.reversed)
NSColor.red.setFill()
path.fill()
OK
let path = NSBezierPath()
//
path.windingRule = .evenOdd
path.appendRect(NSRect(x: 10, y: 10, width: 190, height: 150))
path.appendOval(in: NSRect(x: 50, y: 50, width: 80, height: 70))
NSColor.red.setFill()
path.fill()
let path = NSBezierPath()
path.appendRoundedRect(NSRect(x: 0, y: 0, width: 100, height: 100),
xRadius: 15, yRadius: 15)
path.transform(using: AffineTransform(translationByX: -50, byY: -50))
path.transform(using: AffineTransform(scaleByX: 1.2, byY: 1.4))
path.transform(using: AffineTransform(rotationByRadians: CGFloat.pi / 3))
path.transform(using: AffineTransform(translationByX: 120, byY: 120))
path.fill()
→
π / 3 60°
class CustomView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let path = NSBezierPath()
NSColor.black.set()
path.windingRule = NSBezierPath.WindingRule.evenOdd
path.appendRect(self.frame)
let apple = NSBezierPath()
// Apple
apple.move(to: NSPoint(x: 110.89, y: 99.2))
apple.curve(to: NSPoint(x: 105.97, y: 108.09), controlPoint1: NSPoint(x: 109.5, y: 102.41), controlPoint2: NSPoint(x: 107.87, y: 105.37))
apple.curve(to: NSPoint(x: 99.64, y: 115.79), controlPoint1: NSPoint(x: 103.39, y: 111.8), controlPoint2: NSPoint(x: 101.27, y: 114.37))
apple.curve(to: NSPoint(x: 91.5, y: 119.4), controlPoint1: NSPoint(x: 97.11, y: 118.13), controlPoint2: NSPoint(x: 94.4, y: 119.33))
apple.curve(to: NSPoint(x: 83.99, y: 117.59), controlPoint1: NSPoint(x: 89.42, y: 119.4), controlPoint2: NSPoint(x: 86.91, y: 118.8))
apple.curve(to: NSPoint(x: 75.9, y: 115.79), controlPoint1: NSPoint(x: 81.06, y: 116.39), controlPoint2: NSPoint(x: 78.36, y: 115.79))
apple.curve(to: NSPoint(x: 67.58, y: 117.59), controlPoint1: NSPoint(x: 73.31, y: 115.79), controlPoint2: NSPoint(x: 70.54, y: 116.39))
apple.curve(to: NSPoint(x: 60.39, y: 119.49), controlPoint1: NSPoint(x: 64.61, y: 118.8), controlPoint2: NSPoint(x: 62.21, y: 119.43))
apple.curve(to: NSPoint(x: 52.07, y: 115.79), controlPoint1: NSPoint(x: 57.6, y: 119.61), controlPoint2: NSPoint(x: 54.83, y: 118.38))
apple.curve(to: NSPoint(x: 45.44, y: 107.82), controlPoint1: NSPoint(x: 50.3, y: 114.24), controlPoint2: NSPoint(x: 48.09, y: 111.58))
apple.curve(to: NSPoint(x: 38.44, y: 93.82), controlPoint1: NSPoint(x: 42.6, y: 103.8), controlPoint2: NSPoint(x: 40.27, y: 99.14))
apple.curve(to: NSPoint(x: 35.5, y: 77.15), controlPoint1: NSPoint(x: 36.48, y: 88.09), controlPoint2: NSPoint(x: 35.5, y: 82.53))
apple.curve(to: NSPoint(x: 39.48, y: 61.21), controlPoint1: NSPoint(x: 35.5, y: 70.98), controlPoint2: NSPoint(x: 36.82, y: 65.67))
apple.curve(to: NSPoint(x: 47.8, y: 52.74), controlPoint1: NSPoint(x: 41.56, y: 57.63), controlPoint2: NSPoint(x: 44.33, y: 54.81))
apple.curve(to: NSPoint(x: 59.06, y: 49.54), controlPoint1: NSPoint(x: 51.27, y: 50.67), controlPoint2: NSPoint(x: 55.02, y: 49.61))
apple.curve(to: NSPoint(x: 67.76, y: 51.58), controlPoint1: NSPoint(x: 61.27, y: 49.54), controlPoint2: NSPoint(x: 64.16, y: 50.23))
apple.curve(to: NSPoint(x: 74.67, y: 53.62), controlPoint1: NSPoint(x: 71.35, y: 52.94), controlPoint2: NSPoint(x: 73.66, y: 53.62))
apple.curve(to: NSPoint(x: 82.33, y: 51.22), controlPoint1: NSPoint(x: 75.42, y: 53.62), controlPoint2: NSPoint(x: 77.98, y: 52.82))
apple.curve(to: NSPoint(x: 92.73, y: 49.36), controlPoint1: NSPoint(x: 86.43, y: 49.73), controlPoint2: NSPoint(x: 89.9, y: 49.12))
apple.curve(to: NSPoint(x: 110.05, y: 58.53), controlPoint1: NSPoint(x: 100.43, y: 49.98), controlPoint2: NSPoint(x: 106.2, y: 53.03))
apple.curve(to: NSPoint(x: 99.83, y: 76.13), controlPoint1: NSPoint(x: 103.17, y: 62.72), controlPoint2: NSPoint(x: 99.77, y: 68.59))
apple.curve(to: NSPoint(x: 106.17, y: 90.76), controlPoint1: NSPoint(x: 99.89, y: 82), controlPoint2: NSPoint(x: 102.01, y: 86.88))
apple.curve(to: NSPoint(x: 112.5, y: 94.94), controlPoint1: NSPoint(x: 108.05, y: 92.56), controlPoint2: NSPoint(x: 110.16, y: 93.95))
apple.curve(to: NSPoint(x: 110.89, y: 99.2), controlPoint1: NSPoint(x: 111.99, y: 96.42), controlPoint2: NSPoint(x: 111.46, y: 97.84))
// Leaf
apple.move(to: NSPoint(x: 93.25, y: 29.36))
apple.curve(to: NSPoint(x: 88.25, y: 42.23), controlPoint1: NSPoint(x: 93.25, y: 33.96), controlPoint2: NSPoint(x: 91.58, y: 38.26))
apple.curve(to: NSPoint(x: 74.1, y: 49.26), controlPoint1: NSPoint(x: 84.23, y: 46.96), controlPoint2: NSPoint(x: 79.37, y: 49.69))
apple.curve(to: NSPoint(x: 74, y: 47.52), controlPoint1: NSPoint(x: 74.03, y: 48.71), controlPoint2: NSPoint(x: 74, y: 48.13))
apple.curve(to: NSPoint(x: 79.3, y: 34.51), controlPoint1: NSPoint(x: 74, y: 43.1), controlPoint2: NSPoint(x: 75.91, y: 38.38))
apple.curve(to: NSPoint(x: 85.76, y: 29.63), controlPoint1: NSPoint(x: 80.99, y: 32.55), controlPoint2: NSPoint(x: 83.15, y: 30.93))
apple.curve(to: NSPoint(x: 93.15, y: 27.52), controlPoint1: NSPoint(x: 88.37, y: 28.35), controlPoint2: NSPoint(x: 90.83, y: 27.65))
apple.curve(to: NSPoint(x: 93.25, y: 29.36), controlPoint1: NSPoint(x: 93.22, y: 28.14), controlPoint2: NSPoint(x: 93.25, y: 28.75))
apple.line(to: NSPoint(x: 93.25, y: 29.36))
apple.close()
apple.transform(using: AffineTransform(scaleByX: 1, byY: -1))
apple.transform(using: AffineTransform(translationByX: -75, byY: 77))
apple.transform(using: AffineTransform(scale: 2.0))
apple.transform(using: AffineTransform(translationByX: frame.midX, byY: frame.midY))
path.append(apple)
path.fill()
}
}
class CustomView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let path = NSBezierPath()
NSColor.black.set()
path.windingRule = NSBezierPath.WindingRule.evenOdd
path.appendRect(self.frame)
let apple = NSBezierPath()
// Apple
apple.move(to: NSPoint(x: 110.89, y: 99.2))
apple.curve(to: NSPoint(x: 105.97, y: 108.09), controlPoint1: NSPoint(x: 109.5, y: 102.41), controlPoint2: NSPoint(x: 107.87, y: 105.37))
apple.curve(to: NSPoint(x: 99.64, y: 115.79), controlPoint1: NSPoint(x: 103.39, y: 111.8), controlPoint2: NSPoint(x: 101.27, y: 114.37))
apple.curve(to: NSPoint(x: 91.5, y: 119.4), controlPoint1: NSPoint(x: 97.11, y: 118.13), controlPoint2: NSPoint(x: 94.4, y: 119.33))
apple.curve(to: NSPoint(x: 83.99, y: 117.59), controlPoint1: NSPoint(x: 89.42, y: 119.4), controlPoint2: NSPoint(x: 86.91, y: 118.8))
apple.curve(to: NSPoint(x: 75.9, y: 115.79), controlPoint1: NSPoint(x: 81.06, y: 116.39), controlPoint2: NSPoint(x: 78.36, y: 115.79))
apple.curve(to: NSPoint(x: 67.58, y: 117.59), controlPoint1: NSPoint(x: 73.31, y: 115.79), controlPoint2: NSPoint(x: 70.54, y: 116.39))
apple.curve(to: NSPoint(x: 60.39, y: 119.49), controlPoint1: NSPoint(x: 64.61, y: 118.8), controlPoint2: NSPoint(x: 62.21, y: 119.43))
apple.curve(to: NSPoint(x: 52.07, y: 115.79), controlPoint1: NSPoint(x: 57.6, y: 119.61), controlPoint2: NSPoint(x: 54.83, y: 118.38))
apple.curve(to: NSPoint(x: 45.44, y: 107.82), controlPoint1: NSPoint(x: 50.3, y: 114.24), controlPoint2: NSPoint(x: 48.09, y: 111.58))
apple.curve(to: NSPoint(x: 38.44, y: 93.82), controlPoint1: NSPoint(x: 42.6, y: 103.8), controlPoint2: NSPoint(x: 40.27, y: 99.14))
apple.curve(to: NSPoint(x: 35.5, y: 77.15), controlPoint1: NSPoint(x: 36.48, y: 88.09), controlPoint2: NSPoint(x: 35.5, y: 82.53))
apple.curve(to: NSPoint(x: 39.48, y: 61.21), controlPoint1: NSPoint(x: 35.5, y: 70.98), controlPoint2: NSPoint(x: 36.82, y: 65.67))
apple.curve(to: NSPoint(x: 47.8, y: 52.74), controlPoint1: NSPoint(x: 41.56, y: 57.63), controlPoint2: NSPoint(x: 44.33, y: 54.81))
apple.curve(to: NSPoint(x: 59.06, y: 49.54), controlPoint1: NSPoint(x: 51.27, y: 50.67), controlPoint2: NSPoint(x: 55.02, y: 49.61))
apple.curve(to: NSPoint(x: 67.76, y: 51.58), controlPoint1: NSPoint(x: 61.27, y: 49.54), controlPoint2: NSPoint(x: 64.16, y: 50.23))
apple.curve(to: NSPoint(x: 74.67, y: 53.62), controlPoint1: NSPoint(x: 71.35, y: 52.94), controlPoint2: NSPoint(x: 73.66, y: 53.62))
apple.curve(to: NSPoint(x: 82.33, y: 51.22), controlPoint1: NSPoint(x: 75.42, y: 53.62), controlPoint2: NSPoint(x: 77.98, y: 52.82))
apple.curve(to: NSPoint(x: 92.73, y: 49.36), controlPoint1: NSPoint(x: 86.43, y: 49.73), controlPoint2: NSPoint(x: 89.9, y: 49.12))
apple.curve(to: NSPoint(x: 110.05, y: 58.53), controlPoint1: NSPoint(x: 100.43, y: 49.98), controlPoint2: NSPoint(x: 106.2, y: 53.03))
apple.curve(to: NSPoint(x: 99.83, y: 76.13), controlPoint1: NSPoint(x: 103.17, y: 62.72), controlPoint2: NSPoint(x: 99.77, y: 68.59))
apple.curve(to: NSPoint(x: 106.17, y: 90.76), controlPoint1: NSPoint(x: 99.89, y: 82), controlPoint2: NSPoint(x: 102.01, y: 86.88))
apple.curve(to: NSPoint(x: 112.5, y: 94.94), controlPoint1: NSPoint(x: 108.05, y: 92.56), controlPoint2: NSPoint(x: 110.16, y: 93.95))
apple.curve(to: NSPoint(x: 110.89, y: 99.2), controlPoint1: NSPoint(x: 111.99, y: 96.42), controlPoint2: NSPoint(x: 111.46, y: 97.84))
// Leaf
apple.move(to: NSPoint(x: 93.25, y: 29.36))
apple.curve(to: NSPoint(x: 88.25, y: 42.23), controlPoint1: NSPoint(x: 93.25, y: 33.96), controlPoint2: NSPoint(x: 91.58, y: 38.26))
apple.curve(to: NSPoint(x: 74.1, y: 49.26), controlPoint1: NSPoint(x: 84.23, y: 46.96), controlPoint2: NSPoint(x: 79.37, y: 49.69))
apple.curve(to: NSPoint(x: 74, y: 47.52), controlPoint1: NSPoint(x: 74.03, y: 48.71), controlPoint2: NSPoint(x: 74, y: 48.13))
apple.curve(to: NSPoint(x: 79.3, y: 34.51), controlPoint1: NSPoint(x: 74, y: 43.1), controlPoint2: NSPoint(x: 75.91, y: 38.38))
apple.curve(to: NSPoint(x: 85.76, y: 29.63), controlPoint1: NSPoint(x: 80.99, y: 32.55), controlPoint2: NSPoint(x: 83.15, y: 30.93))
apple.curve(to: NSPoint(x: 93.15, y: 27.52), controlPoint1: NSPoint(x: 88.37, y: 28.35), controlPoint2: NSPoint(x: 90.83, y: 27.65))
apple.curve(to: NSPoint(x: 93.25, y: 29.36), controlPoint1: NSPoint(x: 93.22, y: 28.14), controlPoint2: NSPoint(x: 93.25, y: 28.75))
apple.line(to: NSPoint(x: 93.25, y: 29.36))
apple.close()
apple.transform(using: AffineTransform(scaleByX: 1, byY: -1))
apple.transform(using: AffineTransform(translationByX: -75, byY: 77))
apple.transform(using: AffineTransform(scale: 2.0))
apple.transform(using: AffineTransform(translationByX: frame.midX, byY: frame.midY))
path.append(apple)
path.fill()
}
} 


⚠


⚠
...
ref. Apple Inc. "Graphics Contexts" (2012)
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaDrawingGuide/GraphicsContexts/GraphicsContexts.html
source outclear exclusionsource in
multiplyhue color burnluminosity
NSCompositingOperation
class CustomView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard let context = NSGraphicsContext.current else { return }
context.saveGraphicsState()
//
let pathA = NSBezierPath()
//
//
context.compositingOperation = NSCompositingOperation.clear
//
let pathB = NSBezierPath()
//
context.restoreGraphicsState()
}
}
ScreenPointer clear
let path = NSBezierPath()
path.appendOval(in: NSRect(x: 10, y: 10, width: 200, height: 200))
let pattern = NSImage(imageLiteralResourceName: "pattern")
NSColor(patternImage: pattern).setFill()
path.fill()
let start = NSColor(red: 0.549, green: 0.757, blue: 0.847, alpha: 1.0)
let endA = NSColor.clear
let endB = start.withAlphaComponent(0.0)
let gradientA = NSGradient(starting: start, ending: endA)
gradientA?.draw(in: NSRect(x: 5, y: 5, width: 150, height: 150), angle: 90)
let gradientB = NSGradient(starting: start, ending: endB)
gradientB?.draw(in: NSRect(x: 160, y: 5, width: 150, height: 150), angle: 90)
•
•




Thank you!
AppKitでお絵描きしてみよう

More Related Content

Similar to AppKitでお絵描きしてみよう

Smart Room Gesture Control
Smart Room Gesture ControlSmart Room Gesture Control
Smart Room Gesture Control
Giwrgos Paraskevopoulos
 
numdoc
numdocnumdoc
numdoc
webuploader
 
Александр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыраженияАлександр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыражения
CocoaHeads
 
2.3 implicits
2.3 implicits2.3 implicits
2.3 implicits
futurespective
 
Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018
Tracy Lee
 
Language Language Models (in 2023) - OpenAI
Language Language Models (in 2023) - OpenAILanguage Language Models (in 2023) - OpenAI
Language Language Models (in 2023) - OpenAI
SamuelButler15
 
Svm map reduce_slides
Svm map reduce_slidesSvm map reduce_slides
Svm map reduce_slides
Sara Asher
 
ML基本からResNetまで
ML基本からResNetまでML基本からResNetまで
ML基本からResNetまで
Institute of Agricultural Machinery, NARO
 
Exploring Canvas
Exploring CanvasExploring Canvas
Exploring Canvas
Kevin Hoyt
 
Copy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with QtCopy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with Qt
account inactive
 
ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine
Aleksandar Prokopec
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
Mahmoud Samir Fayed
 
Human_Activity_Recognition_Predictive_Model
Human_Activity_Recognition_Predictive_ModelHuman_Activity_Recognition_Predictive_Model
Human_Activity_Recognition_Predictive_Model
David Ritchie
 
Tutorial on convolutional neural networks
Tutorial on convolutional neural networksTutorial on convolutional neural networks
Tutorial on convolutional neural networks
Hojin Yang
 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
Philip Schwarz
 
NTU ML TENSORFLOW
NTU ML TENSORFLOWNTU ML TENSORFLOW
NTU ML TENSORFLOW
Mark Chang
 
EE660_Report_YaxinLiu_8448347171
EE660_Report_YaxinLiu_8448347171EE660_Report_YaxinLiu_8448347171
EE660_Report_YaxinLiu_8448347171
Yaxin Liu
 
Time Series Analysis and Mining with R
Time Series Analysis and Mining with RTime Series Analysis and Mining with R
Time Series Analysis and Mining with R
Yanchang Zhao
 
openFrameworks 007 - 3D
openFrameworks 007 - 3DopenFrameworks 007 - 3D
openFrameworks 007 - 3D
roxlu
 
How to use SVM for data classification
How to use SVM for data classificationHow to use SVM for data classification
How to use SVM for data classification
Yiwei Chen
 

Similar to AppKitでお絵描きしてみよう (20)

Smart Room Gesture Control
Smart Room Gesture ControlSmart Room Gesture Control
Smart Room Gesture Control
 
numdoc
numdocnumdoc
numdoc
 
Александр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыраженияАлександр Зимин – Анимация как средство самовыражения
Александр Зимин – Анимация как средство самовыражения
 
2.3 implicits
2.3 implicits2.3 implicits
2.3 implicits
 
Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018
 
Language Language Models (in 2023) - OpenAI
Language Language Models (in 2023) - OpenAILanguage Language Models (in 2023) - OpenAI
Language Language Models (in 2023) - OpenAI
 
Svm map reduce_slides
Svm map reduce_slidesSvm map reduce_slides
Svm map reduce_slides
 
ML基本からResNetまで
ML基本からResNetまでML基本からResNetまで
ML基本からResNetまで
 
Exploring Canvas
Exploring CanvasExploring Canvas
Exploring Canvas
 
Copy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with QtCopy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with Qt
 
ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine
 
The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189The Ring programming language version 1.6 book - Part 62 of 189
The Ring programming language version 1.6 book - Part 62 of 189
 
Human_Activity_Recognition_Predictive_Model
Human_Activity_Recognition_Predictive_ModelHuman_Activity_Recognition_Predictive_Model
Human_Activity_Recognition_Predictive_Model
 
Tutorial on convolutional neural networks
Tutorial on convolutional neural networksTutorial on convolutional neural networks
Tutorial on convolutional neural networks
 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
 
NTU ML TENSORFLOW
NTU ML TENSORFLOWNTU ML TENSORFLOW
NTU ML TENSORFLOW
 
EE660_Report_YaxinLiu_8448347171
EE660_Report_YaxinLiu_8448347171EE660_Report_YaxinLiu_8448347171
EE660_Report_YaxinLiu_8448347171
 
Time Series Analysis and Mining with R
Time Series Analysis and Mining with RTime Series Analysis and Mining with R
Time Series Analysis and Mining with R
 
openFrameworks 007 - 3D
openFrameworks 007 - 3DopenFrameworks 007 - 3D
openFrameworks 007 - 3D
 
How to use SVM for data classification
How to use SVM for data classificationHow to use SVM for data classification
How to use SVM for data classification
 

Recently uploaded

An Introduction to the Compiler Designss
An Introduction to the Compiler DesignssAn Introduction to the Compiler Designss
An Introduction to the Compiler Designss
ElakkiaU
 
Mechatronics material . Mechanical engineering
Mechatronics material . Mechanical engineeringMechatronics material . Mechanical engineering
Mechatronics material . Mechanical engineering
sachin chaurasia
 
Software Engineering and Project Management - Introduction, Modeling Concepts...
Software Engineering and Project Management - Introduction, Modeling Concepts...Software Engineering and Project Management - Introduction, Modeling Concepts...
Software Engineering and Project Management - Introduction, Modeling Concepts...
Prakhyath Rai
 
4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf
4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf
4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf
Gino153088
 
Transformers design and coooling methods
Transformers design and coooling methodsTransformers design and coooling methods
Transformers design and coooling methods
Roger Rozario
 
OOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming languageOOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming language
PreethaV16
 
一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理
一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理
一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理
nedcocy
 
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICSUNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
vmspraneeth
 
Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...
Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...
Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...
Transcat
 
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
upoux
 
Accident detection system project report.pdf
Accident detection system project report.pdfAccident detection system project report.pdf
Accident detection system project report.pdf
Kamal Acharya
 
Mechanical Engineering on AAI Summer Training Report-003.pdf
Mechanical Engineering on AAI Summer Training Report-003.pdfMechanical Engineering on AAI Summer Training Report-003.pdf
Mechanical Engineering on AAI Summer Training Report-003.pdf
21UME003TUSHARDEB
 
一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理
一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理
一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理
ecqow
 
Height and depth gauge linear metrology.pdf
Height and depth gauge linear metrology.pdfHeight and depth gauge linear metrology.pdf
Height and depth gauge linear metrology.pdf
q30122000
 
Object Oriented Analysis and Design - OOAD
Object Oriented Analysis and Design - OOADObject Oriented Analysis and Design - OOAD
Object Oriented Analysis and Design - OOAD
PreethaV16
 
Open Channel Flow: fluid flow with a free surface
Open Channel Flow: fluid flow with a free surfaceOpen Channel Flow: fluid flow with a free surface
Open Channel Flow: fluid flow with a free surface
Indrajeet sahu
 
5G Radio Network Througput Problem Analysis HCIA.pdf
5G Radio Network Througput Problem Analysis HCIA.pdf5G Radio Network Througput Problem Analysis HCIA.pdf
5G Radio Network Througput Problem Analysis HCIA.pdf
AlvianRamadhani5
 
Applications of artificial Intelligence in Mechanical Engineering.pdf
Applications of artificial Intelligence in Mechanical Engineering.pdfApplications of artificial Intelligence in Mechanical Engineering.pdf
Applications of artificial Intelligence in Mechanical Engineering.pdf
Atif Razi
 
Pressure Relief valve used in flow line to release the over pressure at our d...
Pressure Relief valve used in flow line to release the over pressure at our d...Pressure Relief valve used in flow line to release the over pressure at our d...
Pressure Relief valve used in flow line to release the over pressure at our d...
cannyengineerings
 
一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理
一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理
一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理
upoux
 

Recently uploaded (20)

An Introduction to the Compiler Designss
An Introduction to the Compiler DesignssAn Introduction to the Compiler Designss
An Introduction to the Compiler Designss
 
Mechatronics material . Mechanical engineering
Mechatronics material . Mechanical engineeringMechatronics material . Mechanical engineering
Mechatronics material . Mechanical engineering
 
Software Engineering and Project Management - Introduction, Modeling Concepts...
Software Engineering and Project Management - Introduction, Modeling Concepts...Software Engineering and Project Management - Introduction, Modeling Concepts...
Software Engineering and Project Management - Introduction, Modeling Concepts...
 
4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf
4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf
4. Mosca vol I -Fisica-Tipler-5ta-Edicion-Vol-1.pdf
 
Transformers design and coooling methods
Transformers design and coooling methodsTransformers design and coooling methods
Transformers design and coooling methods
 
OOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming languageOOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming language
 
一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理
一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理
一比一原版(爱大毕业证书)爱荷华大学毕业证如何办理
 
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICSUNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
 
Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...
Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...
Tools & Techniques for Commissioning and Maintaining PV Systems W-Animations ...
 
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
 
Accident detection system project report.pdf
Accident detection system project report.pdfAccident detection system project report.pdf
Accident detection system project report.pdf
 
Mechanical Engineering on AAI Summer Training Report-003.pdf
Mechanical Engineering on AAI Summer Training Report-003.pdfMechanical Engineering on AAI Summer Training Report-003.pdf
Mechanical Engineering on AAI Summer Training Report-003.pdf
 
一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理
一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理
一比一原版(CalArts毕业证)加利福尼亚艺术学院毕业证如何办理
 
Height and depth gauge linear metrology.pdf
Height and depth gauge linear metrology.pdfHeight and depth gauge linear metrology.pdf
Height and depth gauge linear metrology.pdf
 
Object Oriented Analysis and Design - OOAD
Object Oriented Analysis and Design - OOADObject Oriented Analysis and Design - OOAD
Object Oriented Analysis and Design - OOAD
 
Open Channel Flow: fluid flow with a free surface
Open Channel Flow: fluid flow with a free surfaceOpen Channel Flow: fluid flow with a free surface
Open Channel Flow: fluid flow with a free surface
 
5G Radio Network Througput Problem Analysis HCIA.pdf
5G Radio Network Througput Problem Analysis HCIA.pdf5G Radio Network Througput Problem Analysis HCIA.pdf
5G Radio Network Througput Problem Analysis HCIA.pdf
 
Applications of artificial Intelligence in Mechanical Engineering.pdf
Applications of artificial Intelligence in Mechanical Engineering.pdfApplications of artificial Intelligence in Mechanical Engineering.pdf
Applications of artificial Intelligence in Mechanical Engineering.pdf
 
Pressure Relief valve used in flow line to release the over pressure at our d...
Pressure Relief valve used in flow line to release the over pressure at our d...Pressure Relief valve used in flow line to release the over pressure at our d...
Pressure Relief valve used in flow line to release the over pressure at our d...
 
一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理
一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理
一比一原版(uofo毕业证书)美国俄勒冈大学毕业证如何办理
 

AppKitでお絵描きしてみよう

  • 4.
  • 5. AppKit • macOS • NSBezierPath • NSGraphicsContext •
  • 6. ref. Apple Inc. "Coordinate system" (2018) https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/CoordinateSystem.html iOS macOS
  • 8. • Core Graphics - CGPath (CGMutablePath) - CGContext • AppKit - NSBezierPath - NSGraphicsContext
  • 9. • Core Graphics - CGPath (CGMutablePath) - CGContext • AppKit - NSBezierPath - NSGraphicsContext 😖
  • 10. • Core Graphics - CGPath (CGMutablePath) - CGContext • AppKit - NSBezierPath - NSGraphicsContext 🤔
  • 15. • Core Graphics - CGPath (CGMutablePath) - CGContext • AppKit - NSBezierPath - NSGraphicsContext
  • 16.
  • 17.
  • 19. class CustomView: NSView { override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) let path = NSBezierPath() path.move(to: NSPoint(x: 10, y: 10)) path.line(to: NSPoint(x: 150, y: 120)) path.curve(to: NSPoint(x: 240, y: 10), controlPoint1: NSPoint(x: 225, y: 180), controlPoint2: NSPoint(x: 240, y: 165)) path.close() path.stroke() } }
  • 20. class CustomView: NSView { override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) } }
  • 21. let path = NSBezierPath() path.move(to: NSPoint(x: 10, y: 10)) →
  • 23. path.curve(to: NSPoint(x: 240, y: 10), controlPoint1: NSPoint(x: 225, y: 180), controlPoint2: NSPoint(x: 240, y: 165)) →
  • 25. • 2 4 • ⚠ P0 P1 P2 P3P0 P1
  • 27. path.relativeMove(to: NSPoint.zero) path.relativeLine(to: NSPoint.zero) path.relativeCurve(to: NSPoint.zero, controlPoint1: NSPoint.zero, controlPoint2: NSPoint.zero) ※
  • 28. let face = NSBezierPath(ovalIn: NSRect(x: 60, y: 40, width: 80, height: 80)) let earL = NSBezierPath(ovalIn: NSRect(x: 50, y: 105, width: 40, height: 40)) let earR = NSBezierPath(ovalIn: NSRect(x: 110, y: 105, width: 40, height: 40)) // face.append(earL) face.append(earR) face.fill()
  • 29. // path.lineWidth = 3 // path.lineCapStyle = .round // path.lineJoinStyle = .bevel // path.miterLimit = 5 // path.setLineDash([8.0, 12.0], count: 2, phase: 0)
  • 30. extension NSBezierPath { func printPathElement() { var points = [CGPoint](repeating: CGPoint.zero, count: 3) for i in (0 ..< self.elementCount) { switch self.element(at: i, associatedPoints: &points) { case .moveTo: print("move:", points[0]) case .lineTo: print("line to:", points[0]) case .curveTo: print("curve to:", points[2]) print("controlPoint1:", points[0]) print("controlPoint2:", points[1]) case.closePath: print("close") @unknown default: fatalError() } } } }
  • 32.
  • 33.
  • 34. let path = NSBezierPath() path.appendRect(NSRect(x: 10, y: 10, width: 190, height: 150)) path.appendOval(in: NSRect(x: 40, y: 30, width: 70, height: 60)) NSColor.red.setFill() path.fill()
  • 35.
  • 36.
  • 37. let path = NSBezierPath() path.appendRect(NSRect(x: 10, y: 10, width: 190, height: 150)) let ellipse = NSBezierPath() ellipse.appendOval(in: NSRect(x: 50, y: 50, width: 80, height: 70)) // path.append(ellipse.reversed) NSColor.red.setFill() path.fill() OK
  • 38. let path = NSBezierPath() // path.windingRule = .evenOdd path.appendRect(NSRect(x: 10, y: 10, width: 190, height: 150)) path.appendOval(in: NSRect(x: 50, y: 50, width: 80, height: 70)) NSColor.red.setFill() path.fill()
  • 39. let path = NSBezierPath() path.appendRoundedRect(NSRect(x: 0, y: 0, width: 100, height: 100), xRadius: 15, yRadius: 15) path.transform(using: AffineTransform(translationByX: -50, byY: -50)) path.transform(using: AffineTransform(scaleByX: 1.2, byY: 1.4)) path.transform(using: AffineTransform(rotationByRadians: CGFloat.pi / 3)) path.transform(using: AffineTransform(translationByX: 120, byY: 120)) path.fill() →
  • 40. π / 3 60°
  • 41. class CustomView: NSView { override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) let path = NSBezierPath() NSColor.black.set() path.windingRule = NSBezierPath.WindingRule.evenOdd path.appendRect(self.frame) let apple = NSBezierPath() // Apple apple.move(to: NSPoint(x: 110.89, y: 99.2)) apple.curve(to: NSPoint(x: 105.97, y: 108.09), controlPoint1: NSPoint(x: 109.5, y: 102.41), controlPoint2: NSPoint(x: 107.87, y: 105.37)) apple.curve(to: NSPoint(x: 99.64, y: 115.79), controlPoint1: NSPoint(x: 103.39, y: 111.8), controlPoint2: NSPoint(x: 101.27, y: 114.37)) apple.curve(to: NSPoint(x: 91.5, y: 119.4), controlPoint1: NSPoint(x: 97.11, y: 118.13), controlPoint2: NSPoint(x: 94.4, y: 119.33)) apple.curve(to: NSPoint(x: 83.99, y: 117.59), controlPoint1: NSPoint(x: 89.42, y: 119.4), controlPoint2: NSPoint(x: 86.91, y: 118.8)) apple.curve(to: NSPoint(x: 75.9, y: 115.79), controlPoint1: NSPoint(x: 81.06, y: 116.39), controlPoint2: NSPoint(x: 78.36, y: 115.79)) apple.curve(to: NSPoint(x: 67.58, y: 117.59), controlPoint1: NSPoint(x: 73.31, y: 115.79), controlPoint2: NSPoint(x: 70.54, y: 116.39)) apple.curve(to: NSPoint(x: 60.39, y: 119.49), controlPoint1: NSPoint(x: 64.61, y: 118.8), controlPoint2: NSPoint(x: 62.21, y: 119.43)) apple.curve(to: NSPoint(x: 52.07, y: 115.79), controlPoint1: NSPoint(x: 57.6, y: 119.61), controlPoint2: NSPoint(x: 54.83, y: 118.38)) apple.curve(to: NSPoint(x: 45.44, y: 107.82), controlPoint1: NSPoint(x: 50.3, y: 114.24), controlPoint2: NSPoint(x: 48.09, y: 111.58)) apple.curve(to: NSPoint(x: 38.44, y: 93.82), controlPoint1: NSPoint(x: 42.6, y: 103.8), controlPoint2: NSPoint(x: 40.27, y: 99.14)) apple.curve(to: NSPoint(x: 35.5, y: 77.15), controlPoint1: NSPoint(x: 36.48, y: 88.09), controlPoint2: NSPoint(x: 35.5, y: 82.53)) apple.curve(to: NSPoint(x: 39.48, y: 61.21), controlPoint1: NSPoint(x: 35.5, y: 70.98), controlPoint2: NSPoint(x: 36.82, y: 65.67)) apple.curve(to: NSPoint(x: 47.8, y: 52.74), controlPoint1: NSPoint(x: 41.56, y: 57.63), controlPoint2: NSPoint(x: 44.33, y: 54.81)) apple.curve(to: NSPoint(x: 59.06, y: 49.54), controlPoint1: NSPoint(x: 51.27, y: 50.67), controlPoint2: NSPoint(x: 55.02, y: 49.61)) apple.curve(to: NSPoint(x: 67.76, y: 51.58), controlPoint1: NSPoint(x: 61.27, y: 49.54), controlPoint2: NSPoint(x: 64.16, y: 50.23)) apple.curve(to: NSPoint(x: 74.67, y: 53.62), controlPoint1: NSPoint(x: 71.35, y: 52.94), controlPoint2: NSPoint(x: 73.66, y: 53.62)) apple.curve(to: NSPoint(x: 82.33, y: 51.22), controlPoint1: NSPoint(x: 75.42, y: 53.62), controlPoint2: NSPoint(x: 77.98, y: 52.82)) apple.curve(to: NSPoint(x: 92.73, y: 49.36), controlPoint1: NSPoint(x: 86.43, y: 49.73), controlPoint2: NSPoint(x: 89.9, y: 49.12)) apple.curve(to: NSPoint(x: 110.05, y: 58.53), controlPoint1: NSPoint(x: 100.43, y: 49.98), controlPoint2: NSPoint(x: 106.2, y: 53.03)) apple.curve(to: NSPoint(x: 99.83, y: 76.13), controlPoint1: NSPoint(x: 103.17, y: 62.72), controlPoint2: NSPoint(x: 99.77, y: 68.59)) apple.curve(to: NSPoint(x: 106.17, y: 90.76), controlPoint1: NSPoint(x: 99.89, y: 82), controlPoint2: NSPoint(x: 102.01, y: 86.88)) apple.curve(to: NSPoint(x: 112.5, y: 94.94), controlPoint1: NSPoint(x: 108.05, y: 92.56), controlPoint2: NSPoint(x: 110.16, y: 93.95)) apple.curve(to: NSPoint(x: 110.89, y: 99.2), controlPoint1: NSPoint(x: 111.99, y: 96.42), controlPoint2: NSPoint(x: 111.46, y: 97.84)) // Leaf apple.move(to: NSPoint(x: 93.25, y: 29.36)) apple.curve(to: NSPoint(x: 88.25, y: 42.23), controlPoint1: NSPoint(x: 93.25, y: 33.96), controlPoint2: NSPoint(x: 91.58, y: 38.26)) apple.curve(to: NSPoint(x: 74.1, y: 49.26), controlPoint1: NSPoint(x: 84.23, y: 46.96), controlPoint2: NSPoint(x: 79.37, y: 49.69)) apple.curve(to: NSPoint(x: 74, y: 47.52), controlPoint1: NSPoint(x: 74.03, y: 48.71), controlPoint2: NSPoint(x: 74, y: 48.13)) apple.curve(to: NSPoint(x: 79.3, y: 34.51), controlPoint1: NSPoint(x: 74, y: 43.1), controlPoint2: NSPoint(x: 75.91, y: 38.38)) apple.curve(to: NSPoint(x: 85.76, y: 29.63), controlPoint1: NSPoint(x: 80.99, y: 32.55), controlPoint2: NSPoint(x: 83.15, y: 30.93)) apple.curve(to: NSPoint(x: 93.15, y: 27.52), controlPoint1: NSPoint(x: 88.37, y: 28.35), controlPoint2: NSPoint(x: 90.83, y: 27.65)) apple.curve(to: NSPoint(x: 93.25, y: 29.36), controlPoint1: NSPoint(x: 93.22, y: 28.14), controlPoint2: NSPoint(x: 93.25, y: 28.75)) apple.line(to: NSPoint(x: 93.25, y: 29.36)) apple.close() apple.transform(using: AffineTransform(scaleByX: 1, byY: -1)) apple.transform(using: AffineTransform(translationByX: -75, byY: 77)) apple.transform(using: AffineTransform(scale: 2.0)) apple.transform(using: AffineTransform(translationByX: frame.midX, byY: frame.midY)) path.append(apple) path.fill() } }
  • 42. class CustomView: NSView { override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) let path = NSBezierPath() NSColor.black.set() path.windingRule = NSBezierPath.WindingRule.evenOdd path.appendRect(self.frame) let apple = NSBezierPath() // Apple apple.move(to: NSPoint(x: 110.89, y: 99.2)) apple.curve(to: NSPoint(x: 105.97, y: 108.09), controlPoint1: NSPoint(x: 109.5, y: 102.41), controlPoint2: NSPoint(x: 107.87, y: 105.37)) apple.curve(to: NSPoint(x: 99.64, y: 115.79), controlPoint1: NSPoint(x: 103.39, y: 111.8), controlPoint2: NSPoint(x: 101.27, y: 114.37)) apple.curve(to: NSPoint(x: 91.5, y: 119.4), controlPoint1: NSPoint(x: 97.11, y: 118.13), controlPoint2: NSPoint(x: 94.4, y: 119.33)) apple.curve(to: NSPoint(x: 83.99, y: 117.59), controlPoint1: NSPoint(x: 89.42, y: 119.4), controlPoint2: NSPoint(x: 86.91, y: 118.8)) apple.curve(to: NSPoint(x: 75.9, y: 115.79), controlPoint1: NSPoint(x: 81.06, y: 116.39), controlPoint2: NSPoint(x: 78.36, y: 115.79)) apple.curve(to: NSPoint(x: 67.58, y: 117.59), controlPoint1: NSPoint(x: 73.31, y: 115.79), controlPoint2: NSPoint(x: 70.54, y: 116.39)) apple.curve(to: NSPoint(x: 60.39, y: 119.49), controlPoint1: NSPoint(x: 64.61, y: 118.8), controlPoint2: NSPoint(x: 62.21, y: 119.43)) apple.curve(to: NSPoint(x: 52.07, y: 115.79), controlPoint1: NSPoint(x: 57.6, y: 119.61), controlPoint2: NSPoint(x: 54.83, y: 118.38)) apple.curve(to: NSPoint(x: 45.44, y: 107.82), controlPoint1: NSPoint(x: 50.3, y: 114.24), controlPoint2: NSPoint(x: 48.09, y: 111.58)) apple.curve(to: NSPoint(x: 38.44, y: 93.82), controlPoint1: NSPoint(x: 42.6, y: 103.8), controlPoint2: NSPoint(x: 40.27, y: 99.14)) apple.curve(to: NSPoint(x: 35.5, y: 77.15), controlPoint1: NSPoint(x: 36.48, y: 88.09), controlPoint2: NSPoint(x: 35.5, y: 82.53)) apple.curve(to: NSPoint(x: 39.48, y: 61.21), controlPoint1: NSPoint(x: 35.5, y: 70.98), controlPoint2: NSPoint(x: 36.82, y: 65.67)) apple.curve(to: NSPoint(x: 47.8, y: 52.74), controlPoint1: NSPoint(x: 41.56, y: 57.63), controlPoint2: NSPoint(x: 44.33, y: 54.81)) apple.curve(to: NSPoint(x: 59.06, y: 49.54), controlPoint1: NSPoint(x: 51.27, y: 50.67), controlPoint2: NSPoint(x: 55.02, y: 49.61)) apple.curve(to: NSPoint(x: 67.76, y: 51.58), controlPoint1: NSPoint(x: 61.27, y: 49.54), controlPoint2: NSPoint(x: 64.16, y: 50.23)) apple.curve(to: NSPoint(x: 74.67, y: 53.62), controlPoint1: NSPoint(x: 71.35, y: 52.94), controlPoint2: NSPoint(x: 73.66, y: 53.62)) apple.curve(to: NSPoint(x: 82.33, y: 51.22), controlPoint1: NSPoint(x: 75.42, y: 53.62), controlPoint2: NSPoint(x: 77.98, y: 52.82)) apple.curve(to: NSPoint(x: 92.73, y: 49.36), controlPoint1: NSPoint(x: 86.43, y: 49.73), controlPoint2: NSPoint(x: 89.9, y: 49.12)) apple.curve(to: NSPoint(x: 110.05, y: 58.53), controlPoint1: NSPoint(x: 100.43, y: 49.98), controlPoint2: NSPoint(x: 106.2, y: 53.03)) apple.curve(to: NSPoint(x: 99.83, y: 76.13), controlPoint1: NSPoint(x: 103.17, y: 62.72), controlPoint2: NSPoint(x: 99.77, y: 68.59)) apple.curve(to: NSPoint(x: 106.17, y: 90.76), controlPoint1: NSPoint(x: 99.89, y: 82), controlPoint2: NSPoint(x: 102.01, y: 86.88)) apple.curve(to: NSPoint(x: 112.5, y: 94.94), controlPoint1: NSPoint(x: 108.05, y: 92.56), controlPoint2: NSPoint(x: 110.16, y: 93.95)) apple.curve(to: NSPoint(x: 110.89, y: 99.2), controlPoint1: NSPoint(x: 111.99, y: 96.42), controlPoint2: NSPoint(x: 111.46, y: 97.84)) // Leaf apple.move(to: NSPoint(x: 93.25, y: 29.36)) apple.curve(to: NSPoint(x: 88.25, y: 42.23), controlPoint1: NSPoint(x: 93.25, y: 33.96), controlPoint2: NSPoint(x: 91.58, y: 38.26)) apple.curve(to: NSPoint(x: 74.1, y: 49.26), controlPoint1: NSPoint(x: 84.23, y: 46.96), controlPoint2: NSPoint(x: 79.37, y: 49.69)) apple.curve(to: NSPoint(x: 74, y: 47.52), controlPoint1: NSPoint(x: 74.03, y: 48.71), controlPoint2: NSPoint(x: 74, y: 48.13)) apple.curve(to: NSPoint(x: 79.3, y: 34.51), controlPoint1: NSPoint(x: 74, y: 43.1), controlPoint2: NSPoint(x: 75.91, y: 38.38)) apple.curve(to: NSPoint(x: 85.76, y: 29.63), controlPoint1: NSPoint(x: 80.99, y: 32.55), controlPoint2: NSPoint(x: 83.15, y: 30.93)) apple.curve(to: NSPoint(x: 93.15, y: 27.52), controlPoint1: NSPoint(x: 88.37, y: 28.35), controlPoint2: NSPoint(x: 90.83, y: 27.65)) apple.curve(to: NSPoint(x: 93.25, y: 29.36), controlPoint1: NSPoint(x: 93.22, y: 28.14), controlPoint2: NSPoint(x: 93.25, y: 28.75)) apple.line(to: NSPoint(x: 93.25, y: 29.36)) apple.close() apple.transform(using: AffineTransform(scaleByX: 1, byY: -1)) apple.transform(using: AffineTransform(translationByX: -75, byY: 77)) apple.transform(using: AffineTransform(scale: 2.0)) apple.transform(using: AffineTransform(translationByX: frame.midX, byY: frame.midY)) path.append(apple) path.fill() } } 
  • 45.
  • 46.
  • 47. ref. Apple Inc. "Graphics Contexts" (2012) https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaDrawingGuide/GraphicsContexts/GraphicsContexts.html
  • 48.
  • 49. source outclear exclusionsource in multiplyhue color burnluminosity NSCompositingOperation
  • 50. class CustomView: NSView { override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) guard let context = NSGraphicsContext.current else { return } context.saveGraphicsState() // let pathA = NSBezierPath() // // context.compositingOperation = NSCompositingOperation.clear // let pathB = NSBezierPath() // context.restoreGraphicsState() } }
  • 52. let path = NSBezierPath() path.appendOval(in: NSRect(x: 10, y: 10, width: 200, height: 200)) let pattern = NSImage(imageLiteralResourceName: "pattern") NSColor(patternImage: pattern).setFill() path.fill()
  • 53. let start = NSColor(red: 0.549, green: 0.757, blue: 0.847, alpha: 1.0) let endA = NSColor.clear let endB = start.withAlphaComponent(0.0) let gradientA = NSGradient(starting: start, ending: endA) gradientA?.draw(in: NSRect(x: 5, y: 5, width: 150, height: 150), angle: 90) let gradientB = NSGradient(starting: start, ending: endB) gradientB?.draw(in: NSRect(x: 160, y: 5, width: 150, height: 150), angle: 90)
  • 55.
  • 56.
  • 57.