Skip to content

Commit dbeaeb2

Browse files
committed
Added a koala-nose style pupil generator
1 parent 3ef45d1 commit dbeaeb2

File tree

6 files changed

+138
-1
lines changed

6 files changed

+138
-1
lines changed

Art/images/pupil_koala.png

1.49 KB
Loading

Art/qrcode-designs.pcvd

-5.77 KB
Binary file not shown.

Documentation/shape-configuration/pupil-styles.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
| <a href="../../Art/images/pupil_flame.png"><img src="../../Art/images/pupil_flame.png" width="75" /></a> | __flame__ | `QRCode.PixelShape.Flame` | _none_ |
2525
| <a href="../../Art/images/pupil_forest.png"><img src="../../Art/images/pupil_forest.png" width="75" /></a> | __forest__ | `QRCode.PixelShape.Forest` |__Flippable__<br/> |
2626
| <a href="../../Art/images/pupil_hexagonLeaf.png"><img src="../../Art/images/pupil_hexagonLeaf.png" width="75" /></a> | __hexagonLeaf__ | `QRCode.PixelShape.HexagonLeaf` |__Flippable__<br/> |
27+
| <a href="../../Art/images/pupil_koala.png"><img src="../../Art/images/pupil_koala.png" width="75" /></a> | __koala__ | `QRCode.PixelShape.Koala` |__Flippable__<br/> |
2728
| <a href="../../Art/images/pupil_leaf.png"><img src="../../Art/images/pupil_leaf.png" width="75" /></a> | __leaf__ | `QRCode.PixelShape.Leaf` |__Flippable__<br/> |
2829
| <a href="../../Art/images/pupil_orbits.png"><img src="../../Art/images/pupil_orbits.png" width="75" /></a> | __orbits__ | `QRCode.PixelShape.Orbits` | _none_ |
2930
| <a href="../../Art/images/pupil_pinch.png"><img src="../../Art/images/pupil_pinch.png" width="75" /></a> | __pinch__ | `QRCode.PixelShape.Pinch` | _none_ |

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ You can provide an override to the default `EyeShape` pupil shape to change just
373373

374374
If you don't override the pupil shape, it defaults to the eye shape's pupil shape.
375375

376-
<img src="./Art/images/pupil_arrow.png" width="30" title="Arrow" /> <img src="./Art/images/pupil_barsHorizontal.png" width="30" title="Horizontal bars" /> <img src="./Art/images/pupil_barsHorizontalSquare.png" width="30" title="Square horizontal bars" /> <img src="./Art/images/pupil_barsVertical.png" width="30" title="Vertical bars" /> <img src="./Art/images/pupil_barsVerticalSquare.png" width="30" title="Square vertical bars" /> <img src="./Art/images/pupil_blade.png" width="30" title="Blade" /> <img src="./Art/images/pupil_blobby.png" width="30" title="Blobby" /> <img src="./Art/images/pupil_circle.png" width="30" title="Circle" /> <img src="./Art/images/pupil_cloud.png" width="30" title="Cloud" /> <img src="./Art/images/pupil_corneredPixels.png" width="30" title="Cornered pixels" /> <img src="./Art/images/pupil_cross.png" width="30" title="Cross" /> <img src="./Art/images/pupil_crossCurved.png" width="30" title="CrossCurved" /> <img src="./Art/images/pupil_crt.png" width="30" title="CRT" /> <img src="./Art/images/pupil_diagonalStripes.png" width="30" title="Diagonal Stripes" /> <img src="./Art/images/pupil_dotDragHorizontal.png" width="30" title="Dot Drag Horizontal" /> <img src="./Art/images/pupil_dotDragVertical.png" width="30" title="Dot Drag Vertical" /> <img src="./Art/images/pupil_edges.png" width="30" title="Edges" /> <img src="./Art/images/pupil_explode.png" width="30" title="Explode" /> <img src="./Art/images/pupil_fabricScissors.png" width="30" title="Fabric Scissors" /> <img src="./Art/images/pupil_flame.png" width="30" title="Flame" /> <img src="./Art/images/pupil_forest.png" width="30" title="Forest" /> <img src="./Art/images/pupil_hexagonLeaf.png" width="30" title="Hexagon Leaf" /> <img src="./Art/images/pupil_leaf.png" width="30" title="Leaf" /> <img src="./Art/images/pupil_orbits.png" width="30" title="Orbits" /> <img src="./Art/images/pupil_pinch.png" width="30" title="Pinch" /> <img src="./Art/images/pupil_pixels.png" width="30" title="Pixels" /> <img src="./Art/images/pupil_roundedOuter.png" width="30" title="Rounded outer" /> <img src="./Art/images/pupil_roundedPointingIn.png" width="30" title="Rounded Pointing In" /> <img src="./Art/images/pupil_roundedPointingOut.png" width="30" title="Rounded pointing out" /> <img src="./Art/images/pupil_roundedRect.png" width="30" title="Rounded rectangle" /> <img src="./Art/images/pupil_seal.png" width="30" title="Seal" /> <img src="./Art/images/pupil_shield.png" width="30" title="Shield" /> <img src="./Art/images/pupil_spikyCircle.png" width="30" title="Spiky Circle" /> <img src="./Art/images/pupil_square.png" width="30" title="Square" /> <img src="./Art/images/pupil_squircle.png" width="30" title="Squircle" /> <img src="./Art/images/pupil_teardrop.png" width="30" title="Teardrop" /> <img src="./Art/images/pupil_ufo.png" width="30" title="UFO" /> <img src="./Art/images/pupil_ufoRounded.png" width="30" title="UFO Rounded" /> <img src="./Art/images/pupil_usePixelShape.png" width="30" title="Use Pixel Shape" />
376+
<img src="./Art/images/pupil_arrow.png" width="30" title="Arrow" /> <img src="./Art/images/pupil_barsHorizontal.png" width="30" title="Horizontal bars" /> <img src="./Art/images/pupil_barsHorizontalSquare.png" width="30" title="Square horizontal bars" /> <img src="./Art/images/pupil_barsVertical.png" width="30" title="Vertical bars" /> <img src="./Art/images/pupil_barsVerticalSquare.png" width="30" title="Square vertical bars" /> <img src="./Art/images/pupil_blade.png" width="30" title="Blade" /> <img src="./Art/images/pupil_blobby.png" width="30" title="Blobby" /> <img src="./Art/images/pupil_circle.png" width="30" title="Circle" /> <img src="./Art/images/pupil_cloud.png" width="30" title="Cloud" /> <img src="./Art/images/pupil_corneredPixels.png" width="30" title="Cornered pixels" /> <img src="./Art/images/pupil_cross.png" width="30" title="Cross" /> <img src="./Art/images/pupil_crossCurved.png" width="30" title="CrossCurved" /> <img src="./Art/images/pupil_crt.png" width="30" title="CRT" /> <img src="./Art/images/pupil_diagonalStripes.png" width="30" title="Diagonal Stripes" /> <img src="./Art/images/pupil_dotDragHorizontal.png" width="30" title="Dot Drag Horizontal" /> <img src="./Art/images/pupil_dotDragVertical.png" width="30" title="Dot Drag Vertical" /> <img src="./Art/images/pupil_edges.png" width="30" title="Edges" /> <img src="./Art/images/pupil_explode.png" width="30" title="Explode" /> <img src="./Art/images/pupil_fabricScissors.png" width="30" title="Fabric Scissors" /> <img src="./Art/images/pupil_flame.png" width="30" title="Flame" /> <img src="./Art/images/pupil_forest.png" width="30" title="Forest" /> <img src="./Art/images/pupil_hexagonLeaf.png" width="30" title="Hexagon Leaf" /> <img src="./Art/images/pupil_koala.png" width="30" title="Koala" /> <img src="./Art/images/pupil_leaf.png" width="30" title="Leaf" /> <img src="./Art/images/pupil_orbits.png" width="30" title="Orbits" /> <img src="./Art/images/pupil_pinch.png" width="30" title="Pinch" /> <img src="./Art/images/pupil_pixels.png" width="30" title="Pixels" /> <img src="./Art/images/pupil_roundedOuter.png" width="30" title="Rounded outer" /> <img src="./Art/images/pupil_roundedPointingIn.png" width="30" title="Rounded Pointing In" /> <img src="./Art/images/pupil_roundedPointingOut.png" width="30" title="Rounded pointing out" /> <img src="./Art/images/pupil_roundedRect.png" width="30" title="Rounded rectangle" /> <img src="./Art/images/pupil_seal.png" width="30" title="Seal" /> <img src="./Art/images/pupil_shield.png" width="30" title="Shield" /> <img src="./Art/images/pupil_spikyCircle.png" width="30" title="Spiky Circle" /> <img src="./Art/images/pupil_square.png" width="30" title="Square" /> <img src="./Art/images/pupil_squircle.png" width="30" title="Squircle" /> <img src="./Art/images/pupil_teardrop.png" width="30" title="Teardrop" /> <img src="./Art/images/pupil_ufo.png" width="30" title="UFO" /> <img src="./Art/images/pupil_ufoRounded.png" width="30" title="UFO Rounded" /> <img src="./Art/images/pupil_usePixelShape.png" width="30" title="Use Pixel Shape" />
377377

378378
[Pupil style configuration options](./Documentation/shape-configuration/pupil-styles.md)
379379

Sources/QRCode/styles/pupil/QRCodePupilShapeFactory.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ import CoreGraphics
102102
QRCode.PupilShape.DiagonalStripes.self,
103103
QRCode.PupilShape.Arrow.self,
104104
QRCode.PupilShape.Flame.self,
105+
QRCode.PupilShape.Koala.self,
105106
].sorted(by: { a, b in a.Title < b.Title })
106107
}
107108

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//
2+
// Copyright © 2025 Darren Ford. All rights reserved.
3+
//
4+
// MIT license
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7+
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
8+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9+
// permit persons to whom the Software is furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in all copies or substantial
12+
// portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
15+
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
16+
// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18+
//
19+
20+
import CoreGraphics
21+
import Foundation
22+
23+
// MARK: - Pupil shape
24+
25+
public extension QRCode.PupilShape {
26+
/// A Koala-node style pupil shape
27+
@objc(QRCodePupilShapeKoala) class Koala: NSObject, QRCodePupilShapeGenerator {
28+
@objc public static var Name: String { "koala" }
29+
/// The generator title
30+
@objc public static var Title: String { "Koala" }
31+
@objc public static func Create(_ settings: [String : Any]?) -> any QRCodePupilShapeGenerator {
32+
Koala(settings: settings)
33+
}
34+
35+
/// The flip transform to apply to the pupil shape
36+
@objc public var flip: QRCode.Flip = .none
37+
38+
/// Create a koala-node style pupil generator
39+
/// - Parameter flip: The flip transform to apply to the pupil
40+
@objc public init(flip: QRCode.Flip = .none) {
41+
self.flip = flip
42+
super.init()
43+
}
44+
45+
/// Create a koala pupil shape generator using the specified settings
46+
@objc public init(settings: [String: Any]?) {
47+
super.init()
48+
settings?.forEach { (key: String, value: Any) in
49+
_ = self.setSettingValue(value, forKey: key)
50+
}
51+
}
52+
53+
/// Make a copy of the object
54+
@objc public func copyShape() -> any QRCodePupilShapeGenerator {
55+
Koala(flip: self.flip)
56+
}
57+
/// Reset the pupil shape generator back to defaults
58+
@objc public func reset() {
59+
self.flip = .none
60+
}
61+
62+
/// The pupil centered in the 90x90 square
63+
@objc public func pupilPath() -> CGPath {
64+
switch self.flip {
65+
case .none:
66+
return pupilShape__
67+
case .horizontally:
68+
return CGPath.make(forceClosePath: true) { n in
69+
n.addPath(pupilShape__, transform: .init(scaleX: -1, y: 1).translatedBy(x: -90, y: 0))
70+
}
71+
case .vertically:
72+
return CGPath.make(forceClosePath: true) { n in
73+
n.addPath(pupilShape__, transform: .init(scaleX: 1, y: -1).translatedBy(x: 0, y: -90))
74+
}
75+
case .both:
76+
return CGPath.make(forceClosePath: true) { n in
77+
n.addPath(pupilShape__, transform: .init(scaleX: -1, y: -1).translatedBy(x: -90, y: -90))
78+
}
79+
}
80+
}
81+
}
82+
}
83+
84+
// MARK: - Settings
85+
86+
public extension QRCode.PupilShape.Koala {
87+
/// Retrieve the settings for this pupil generator
88+
/// - Returns: A dictionary of settings
89+
@objc func settings() -> [String: Any] {
90+
[QRCode.SettingsKey.flip: self.flip.rawValue]
91+
}
92+
93+
/// Returns true if the generator supports settings values for the given key
94+
@objc func supportsSettingValue(forKey key: String) -> Bool {
95+
key == QRCode.SettingsKey.flip
96+
}
97+
98+
/// Set the key's value in the generator
99+
/// - Parameters:
100+
/// - value: The value to set
101+
/// - key: The setting key
102+
/// - Returns: True if the setting was able to be change, false otherwise
103+
@objc func setSettingValue(_ value: Any?, forKey key: String) -> Bool {
104+
if key == QRCode.SettingsKey.flip,
105+
let which = IntValue(value)
106+
{
107+
self.flip = QRCode.Flip(rawValue: which) ?? .none
108+
return true
109+
}
110+
return false
111+
}
112+
}
113+
114+
// MARK: - Conveniences
115+
116+
public extension QRCodePupilShapeGenerator where Self == QRCode.PupilShape.Koala {
117+
/// Create a koala pupil shape generator
118+
/// - Parameter flip: The flip transform to apply to the pupil
119+
/// - Returns: A pupil shape generator
120+
@inlinable static func koala(flip: QRCode.Flip = .none) -> QRCodePupilShapeGenerator {
121+
QRCode.PupilShape.Koala(flip: flip)
122+
}
123+
}
124+
125+
// MARK: - Designs
126+
127+
private let pupilShape__: CGPath =
128+
CGPath.make { koalapupilPath in
129+
koalapupilPath.move(to: CGPoint(x: 31.62, y: 58.38))
130+
koalapupilPath.curve(to: CGPoint(x: 59.77, y: 49.43), controlPoint1: CGPoint(x: 36.42, y: 63.18), controlPoint2: CGPoint(x: 57.53, y: 56.46))
131+
koalapupilPath.curve(to: CGPoint(x: 40.57, y: 30.23), controlPoint1: CGPoint(x: 62, y: 42.39), controlPoint2: CGPoint(x: 47.61, y: 28))
132+
koalapupilPath.curve(to: CGPoint(x: 31.62, y: 58.38), controlPoint1: CGPoint(x: 33.54, y: 32.47), controlPoint2: CGPoint(x: 26.82, y: 53.58))
133+
koalapupilPath.close()
134+
}
135+
.flippedVertically(height: 90)

0 commit comments

Comments
 (0)