Skip to content

Commit 38aac09

Browse files
committed
Initial commit
0 parents  commit 38aac09

File tree

6 files changed

+213
-0
lines changed

6 files changed

+213
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Jia-Han Wu
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Package.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// swift-tools-version: 5.10
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "swiftui-code39",
8+
platforms: [
9+
.iOS(.v15),
10+
.macOS(.v12),
11+
],
12+
products: [
13+
.library(
14+
name: "Code39",
15+
targets: ["Code39"]
16+
),
17+
],
18+
targets: [
19+
.target(name: "Code39"),
20+
]
21+
)

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# SwiftUI Code39
2+
3+
SwiftUI Code39 is a Swift package that provides an easy way to generate Code 39 barcodes in your SwiftUI applications.
4+
5+
## Installation
6+
7+
To use SwiftUI Code39 in your project, add the following line to your `Package.swift` file:
8+
9+
```swift
10+
dependencies: [
11+
.package(url: "https://github.com/jiahan-wu/swiftui-code39.git", from: "1.0.0")
12+
]
13+
```
14+
15+
Then, import the package in your Swift code:
16+
17+
```swift
18+
import Code39
19+
```
20+
21+
## Usage
22+
23+
To generate a Code 39 barcode, simply create an instance of `Code39View` and provide the desired content as a string:
24+
25+
```swift
26+
struct ContentView: View {
27+
var body: some View {
28+
Code39View("HELLO WORLD")
29+
.frame(width: 296, height: 96)
30+
}
31+
}
32+
```
33+
34+
## Important Note
35+
36+
It is the responsibility of the library user to ensure that the content passed to `Code39View` consists of valid characters supported by Code 39. You can use the `code39SupportedCharacters` set to check if a character is supported:
37+
38+
```swift
39+
let content = "HELLO"
40+
let isValid = content.allSatisfy { code39SupportedCharacters.contains($0) }
41+
```
42+
43+
## License
44+
45+
SwiftUI Code39 is released under the MIT License. See the `LICENSE` file for more information.
46+
47+
## Contributing
48+
49+
Contributions to SwiftUI Code39 are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the GitHub repository.

Sources/Code39/Code39.swift

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// The Swift Programming Language
2+
//
3+
// Code39.swift
4+
//
5+
//
6+
// Created by Jia-Han Wu on 2024/5/4.
7+
//
8+
9+
enum BarWidth {
10+
case narrow
11+
case wide
12+
}
13+
14+
let code39Patterns: [Character: [BarWidth]] = [
15+
" ": [.narrow, .wide, .wide, .narrow, .narrow, .narrow, .wide, .narrow, .narrow],
16+
"$": [.narrow, .wide, .narrow, .wide, .narrow, .wide, .narrow, .narrow, .narrow],
17+
"%": [.narrow, .narrow, .narrow, .wide, .narrow, .wide, .narrow, .wide, .narrow],
18+
"*": [.narrow, .wide, .narrow, .narrow, .wide, .narrow, .wide, .narrow, .narrow],
19+
"+": [.narrow, .wide, .narrow, .narrow, .narrow, .wide, .narrow, .wide, .narrow],
20+
"-": [.narrow, .wide, .narrow, .narrow, .narrow, .narrow, .wide, .narrow, .wide],
21+
".": [ .wide, .wide, .narrow, .narrow, .narrow, .narrow, .wide, .narrow, .narrow],
22+
"/": [.narrow, .wide, .narrow, .wide, .narrow, .narrow, .narrow, .wide, .narrow],
23+
"0": [.narrow, .narrow, .narrow, .wide, .wide, .narrow, .wide, .narrow, .narrow],
24+
"1": [ .wide, .narrow, .narrow, .wide, .narrow, .narrow, .narrow, .narrow, .wide],
25+
"2": [.narrow, .narrow, .wide, .wide, .narrow, .narrow, .narrow, .narrow, .wide],
26+
"3": [ .wide, .narrow, .wide, .wide, .narrow, .narrow, .narrow, .narrow, .narrow],
27+
"4": [.narrow, .narrow, .narrow, .wide, .wide, .narrow, .narrow, .narrow, .wide],
28+
"5": [ .wide, .narrow, .narrow, .wide, .wide, .narrow, .narrow, .narrow, .narrow],
29+
"6": [.narrow, .narrow, .wide, .wide, .wide, .narrow, .narrow, .narrow, .narrow],
30+
"7": [.narrow, .narrow, .narrow, .wide, .narrow, .narrow, .wide, .narrow, .wide],
31+
"8": [ .wide, .narrow, .narrow, .wide, .narrow, .narrow, .wide, .narrow, .narrow],
32+
"9": [.narrow, .narrow, .wide, .wide, .narrow, .narrow, .wide, .narrow, .narrow],
33+
"A": [ .wide, .narrow, .narrow, .narrow, .narrow, .wide, .narrow, .narrow, .wide],
34+
"B": [.narrow, .narrow, .wide, .narrow, .narrow, .wide, .narrow, .narrow, .wide],
35+
"C": [ .wide, .narrow, .wide, .narrow, .narrow, .wide, .narrow, .narrow, .narrow],
36+
"D": [.narrow, .narrow, .narrow, .narrow, .wide, .wide, .narrow, .narrow, .wide],
37+
"E": [ .wide, .narrow, .narrow, .narrow, .wide, .wide, .narrow, .narrow, .narrow],
38+
"F": [.narrow, .narrow, .wide, .narrow, .wide, .wide, .narrow, .narrow, .narrow],
39+
"G": [.narrow, .narrow, .narrow, .narrow, .narrow, .wide, .wide, .narrow, .wide],
40+
"H": [ .wide, .narrow, .narrow, .narrow, .narrow, .wide, .wide, .narrow, .narrow],
41+
"I": [.narrow, .narrow, .wide, .narrow, .narrow, .wide, .wide, .narrow, .narrow],
42+
"J": [.narrow, .narrow, .narrow, .narrow, .wide, .wide, .wide, .narrow, .narrow],
43+
"K": [ .wide, .narrow, .narrow, .narrow, .narrow, .narrow, .narrow, .wide, .wide],
44+
"L": [.narrow, .narrow, .wide, .narrow, .narrow, .narrow, .narrow, .wide, .wide],
45+
"M": [ .wide, .narrow, .wide, .narrow, .narrow, .narrow, .narrow, .wide, .narrow],
46+
"N": [.narrow, .narrow, .narrow, .narrow, .wide, .narrow, .narrow, .wide, .wide],
47+
"O": [ .wide, .narrow, .narrow, .narrow, .wide, .narrow, .narrow, .wide, .narrow],
48+
"P": [.narrow, .narrow, .wide, .narrow, .wide, .narrow, .narrow, .wide, .narrow],
49+
"Q": [.narrow, .narrow, .narrow, .narrow, .narrow, .narrow, .wide, .wide, .wide],
50+
"R": [ .wide, .narrow, .narrow, .narrow, .narrow, .narrow, .wide, .wide, .narrow],
51+
"S": [.narrow, .narrow, .wide, .narrow, .narrow, .narrow, .wide, .wide, .narrow],
52+
"T": [.narrow, .narrow, .narrow, .narrow, .wide, .narrow, .wide, .wide, .narrow],
53+
"U": [ .wide, .wide, .narrow, .narrow, .narrow, .narrow, .narrow, .narrow, .wide],
54+
"V": [.narrow, .wide, .wide, .narrow, .narrow, .narrow, .narrow, .narrow, .wide],
55+
"W": [ .wide, .wide, .wide, .narrow, .narrow, .narrow, .narrow, .narrow, .narrow],
56+
"X": [.narrow, .wide, .narrow, .narrow, .wide, .narrow, .narrow, .narrow, .wide],
57+
"Y": [ .wide, .wide, .narrow, .narrow, .wide, .narrow, .narrow, .narrow, .narrow],
58+
"Z": [.narrow, .wide, .wide, .narrow, .wide, .narrow, .narrow, .narrow, .narrow],
59+
]
60+
61+
func encodeToCode39(_ input: String) -> [BarWidth] {
62+
var encodedBarcode: [BarWidth] = []
63+
64+
encodedBarcode.append(contentsOf: code39Patterns["*"]!)
65+
encodedBarcode.append(.narrow)
66+
67+
for character in input {
68+
encodedBarcode.append(contentsOf: code39Patterns[character]!)
69+
encodedBarcode.append(.narrow)
70+
}
71+
72+
encodedBarcode.append(contentsOf: code39Patterns["*"]!)
73+
74+
return encodedBarcode
75+
}
76+
77+
public let code39SupportedCharacters: Set<Character> = Set(code39Patterns.keys)

Sources/Code39/Code39View.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//
2+
// Code39View.swift
3+
//
4+
//
5+
// Created by Jia-Han Wu on 2024/5/4.
6+
//
7+
8+
import SwiftUI
9+
10+
public struct Code39View: View {
11+
12+
private let barcode: [BarWidth]
13+
14+
public init(_ content: String) {
15+
self.barcode = encodeToCode39(content)
16+
}
17+
18+
public var body: some View {
19+
Canvas { context, size in
20+
let intercharacterGapCount = barcode.count % 9
21+
let narrowBarWidth = size.width / CGFloat(((((barcode.count - intercharacterGapCount) / 9) * 15) + intercharacterGapCount))
22+
var currentX: CGFloat = 0
23+
for (index, barWidth) in barcode.enumerated() {
24+
let barColor: Color = index % 2 == 0 ? .black : .white
25+
let barWidth: CGFloat = barWidth == .narrow ? narrowBarWidth : narrowBarWidth * 3
26+
var barPath = Path()
27+
let barRect = CGRect(x: currentX,
28+
y: 0,
29+
width: barWidth,
30+
height: size.height)
31+
currentX += barWidth
32+
barPath.addRect(barRect)
33+
context.fill(barPath, with: .color(barColor))
34+
}
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)