Skip to content

Commit fd08cda

Browse files
committed
chore: improve font system
1 parent 75c3c60 commit fd08cda

22 files changed

Lines changed: 872 additions & 403 deletions

Sources/OpenSwiftUI/Views/Text Input and Output/Setting a font/Setting a font/Font.swift

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,19 @@ import Foundation
1212
///
1313
/// The system resolves a font's value at the time it uses the font in a given
1414
/// environment because ``Font`` is a late-binding token.
15-
public struct Font : Equatable, Hashable, Sendable {
15+
public struct Font : Sendable {
1616

1717
// private var library: FT_Library?
1818

1919
/// The provider of the font.
20-
let provider: AnyFontBox
20+
let provider: AnyFontProvider
2121

2222
/// Creates a font with the given provider.
2323
///
2424
/// - Parameter provider: The provider of the font.
25-
private init(provider: AnyFontBox) {
25+
private init(provider: AnyFontProvider) {
2626
self.provider = provider
2727
}
28-
29-
public static func == (lhs: Font, rhs: Font) -> Bool {
30-
lhs.provider == rhs.provider
31-
}
3228
}
3329

3430
extension Font {
@@ -228,20 +224,20 @@ extension Font {
228224
/// For fonts created from text styles, it could mean applying emphasized
229225
/// styling, which does not necessarily mean the bold weight specifically,
230226
/// so this modifier is not to be confused with
231-
/// <doc://com.apple.documentation/documentation/OpenSwiftUI/Font/weight(_:)>.
227+
/// <doc://com.apple.documentation/documentation/SwiftUI/Font/weight(_:)>.
232228
///
233229
/// For example:
234230
///
235231
/// Font.body.bold()
236232
///
237233
/// will most likely get you the emphasized version of body text style,
238-
/// which is often in <doc://com.apple.documentation/documentation/OpenSwiftUI/Font/weight/semibold>
234+
/// which is often in <doc://com.apple.documentation/documentation/SwiftUI/Font/weight/semibold>
239235
/// weight. While
240236
///
241237
/// Font.body.weight(.bold)
242238
///
243239
/// will specifically get you the body text style font in the
244-
/// <doc://com.apple.documentation/documentation/OpenSwiftUI/Font/weight/bold>
240+
/// <doc://com.apple.documentation/documentation/SwiftUI/Font/weight/bold>
245241
/// weight.
246242
public func bold() -> Font {
247243
.init(provider: StaticModifierProvider(base: provider, modifier: BoldModifier(true)))
@@ -252,20 +248,20 @@ extension Font {
252248
/// For fonts created from text styles, passing `true` could mean applying
253249
/// emphasized styling, which does not necessarily mean the bold weight
254250
/// specifically, so this modifier is not to be confused with
255-
/// <doc://com.apple.documentation/documentation/OpenSwiftUI/Font/weight(_:)>.
251+
/// <doc://com.apple.documentation/documentation/SwiftUI/Font/weight(_:)>.
256252
///
257253
/// For example:
258254
///
259255
/// Font.body.bold(true)
260256
///
261257
/// will most likely get you the emphasized version of body text style,
262-
/// which is often in <doc://com.apple.documentation/documentation/OpenSwiftUI/Font/weight/semibold>
258+
/// which is often in <doc://com.apple.documentation/documentation/SwiftUI/Font/weight/semibold>
263259
/// weight. While
264260
///
265261
/// Font.body.weight(.bold)
266262
///
267263
/// will specifically get you the body text style font in the
268-
/// <doc://com.apple.documentation/documentation/OpenSwiftUI/Font/weight/bold>
264+
/// <doc://com.apple.documentation/documentation/SwiftUI/Font/weight/bold>
269265
/// weight.
270266
///
271267
/// Using:
@@ -281,7 +277,7 @@ extension Font {
281277

282278
/// Returns a fixed-width font from the same family as the base font.
283279
///
284-
/// If there's no suitable font face in the same family, OpenSwiftUI
280+
/// If there's no suitable font face in the same family, SwiftUI
285281
/// returns a default fixed-width font.
286282
///
287283
/// The following example adds the `monospaced()` modifier to the default
@@ -304,7 +300,7 @@ extension Font {
304300
/// ![A macOS window showing the text Hello, world in a 24-point
305301
/// fixed-width font.](Environment-Font-monospaced-1)
306302
///
307-
/// OpenSwiftUI may provide different fixed-width replacements for standard
303+
/// SwiftUI may provide different fixed-width replacements for standard
308304
/// user interface fonts (such as ``Font/title``, or a system font created
309305
/// with ``Font/system(_:design:)``) than for those same fonts when created
310306
/// by name with ``Font/custom(_:size:)``.
@@ -329,7 +325,7 @@ extension Font {
329325
/// Returns a font adding or removing fixed-width design from the same
330326
/// family as the base font.
331327
///
332-
/// If there's no suitable font face in the same family, OpenSwiftUI
328+
/// If there's no suitable font face in the same family, SwiftUI
333329
/// returns a default font.
334330
///
335331
/// The following example adds the `monospaced()` modifier to the default
@@ -352,7 +348,7 @@ extension Font {
352348
/// ![A macOS window showing the text Hello, world in a 24-point
353349
/// fixed-width font.](Environment-Font-monospaced-1)
354350
///
355-
/// OpenSwiftUI may provide different fixed-width replacements for standard
351+
/// SwiftUI may provide different fixed-width replacements for standard
356352
/// user interface fonts (such as ``Font/title``, or a system font created
357353
/// with ``Font/system(_:design:)``) than for those same fonts when created
358354
/// by name with ``Font/custom(_:size:)``.
@@ -407,13 +403,13 @@ extension Font {
407403

408404
extension Font {
409405

410-
/// The effective OpenSwiftUI font used in any given environment.
406+
/// The effective SwiftUI font used in any given environment.
411407
///
412408
/// The font specified by environment, preferring first any developer
413409
/// spedified font, via ``EnvironmentValues/font``, then any framework
414-
/// specified font, and finally the default OpenSwiftUI font.
410+
/// specified font, and finally the default SwiftUI font.
415411
public static var `default`: Font {
416-
Font.system(size: 16)
412+
fatalError("not implemented yet")
417413
}
418414
}
419415

@@ -465,4 +461,11 @@ extension Font {
465461
public static func system(size: Double, weight: Font.Weight? = nil, design: Font.Design? = nil) -> Font {
466462
.init(provider: SystemProvider(size: size, weight: weight, design: design, textStyle: .body, maximumSize: nil))
467463
}
464+
}
465+
466+
extension Font : Equatable {
467+
468+
public static func == (lhs: Font, rhs: Font) -> Bool {
469+
ObjectIdentifier(lhs.provider) == ObjectIdentifier(rhs.provider)
470+
}
468471
}

Sources/OpenSwiftUI/Views/Text Input and Output/Setting a font/Structures/Font+Atlas.swift

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,40 @@ import Foundation
33
extension Font {
44

55
/// A font atlas.
6-
struct Atlas : Sendable {
6+
struct Atlas : Equatable, Hashable, Sendable {
77

8-
/// The glyphs in the Atlas.
8+
/// The glyphs in the atlas.
99
var glyphs: [Glyph]
1010

11-
/// Create a new atlas with the given glyphs.
12-
///
11+
/// The count of glyphs in the atlas.
12+
var count: Int {
13+
glyphs.count
14+
}
15+
16+
/// Creates a new atlas with the given glyphs.
17+
///
1318
/// - Parameter glyphs: The glyphs in the atlas.
14-
init(_ glyphs: [Glyph]) {
19+
init(glyphs: [Glyph] = []) {
1520
self.glyphs = glyphs
1621
}
22+
23+
/// Adds a new glyph to the atlas.
24+
///
25+
/// - Parameter glyph: The glyph to add to the atlas.
26+
mutating func add(glyph: Glyph) {
27+
glyphs.append(glyph)
28+
}
29+
30+
/// Removes a glyph from the atlas.
31+
///
32+
/// - Parameter glyph: The glyph to remove from the atlas.
33+
mutating func remove(glyph: Glyph) {
34+
glyphs.removeAll { $0.index == glyph.index }
35+
}
36+
37+
/// Clears the atlas.
38+
mutating func clear() {
39+
glyphs.removeAll()
40+
}
1741
}
1842
}

Sources/OpenSwiftUI/Views/Text Input and Output/Setting a font/Structures/Font+Context.swift

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,13 @@
99
import Foundation
1010
import OpenFreeType
1111
import OpenHarfBuzz
12+
import OpenSpatial
1213

1314
extension Font {
1415

1516
/// Information used to resolve a font.
1617
public struct Context {
1718

18-
init() { }
19-
20-
mutating func resolve(_ font: Font) -> Font.Resolved {
21-
fatalError("not implemented yet")
22-
}
23-
24-
mutating func resolve(_ provider: Font.AnyFontBox) -> Font.Resolved {
25-
fatalError("not implemented yet")
26-
}
27-
28-
mutating func resolve(_ provider: Font.NamedProvider) -> Font.Resolved {
29-
fatalError("not implemented yet")
30-
}
31-
32-
mutating func resolve(_ provider: Font.SystemProvider) -> Font.Resolved {
33-
fatalError("not implemented yet")
34-
}
35-
36-
mutating func resolve(_ provider: Any) -> Font.Resolved {
37-
fatalError("not implemented yet")
38-
}
39-
40-
mutating func resolve(_ provider: Font.StaticModifierProvider<ItalicModifier>) -> Font.Resolved {
41-
fatalError("not implemented yet")
42-
}
43-
44-
mutating func resolve(_ provider: Font.StaticModifierProvider<BoldModifier>) -> Font.Resolved {
45-
fatalError("not implemented yet")
46-
}
19+
var resolved: Font.Resolved = .init()
4720
}
48-
}
21+
}

Sources/OpenSwiftUI/Views/Text Input and Output/Setting a font/Structures/Font+Glyph.swift

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,69 @@ import OpenSpatial
33

44
extension Font {
55

6-
/// The glyph in a font.
7-
struct Glyph : @unchecked Sendable {
8-
9-
/// The glyph texture
10-
var texture: UInt32 = 0
6+
/// A glyph in a font.
7+
struct Glyph : Equatable, Hashable, @unchecked Sendable {
118

129
/// The glyph index.
13-
var index: Int = 0
10+
var index: UInt32 = 0
1411

1512
/// The glyph advance.
1613
var advance: Point3D = .zero
1714

18-
/// The gliph offset.
15+
/// The glyph offset.
1916
var offset: Point3D = .zero
2017

2118
/// The glyph bearing.
2219
var bearing: Point3D = .zero
2320

24-
/// The glyph frame.
21+
/// The glyph size.
2522
var size: Size3D = .zero
2623

2724
/// The glyph UV coordinates.
2825
var uv: (u0: Double, v0: Double, u1: Double, v1: Double) = (0, 0, 0, 0)
29-
}
30-
}
3126

32-
extension Font.Glyph : Equatable {
27+
/// The glyph buffer.
28+
var buffer: UnsafeBufferPointer<UInt8>? = nil
3329

34-
/// Check if two glyphs are equal.
35-
///
36-
/// - Parameters:
37-
/// - lhs: The left glyph.
38-
/// - rhs: The right glyph.
39-
/// - Returns: `true` if the glyphs are equal, `false` otherwise.
40-
static func == (lhs: Font.Glyph, rhs: Font.Glyph) -> Bool {
41-
lhs.index == rhs.index &&
42-
lhs.advance == rhs.advance &&
43-
lhs.offset == rhs.offset &&
44-
lhs.bearing == rhs.bearing &&
45-
lhs.size == rhs.size &&
46-
lhs.uv == rhs.uv
47-
}
48-
}
30+
/// Creates a new glyph with the given index, advance, and offset.
31+
///
32+
/// - Parameter index: The glyph index.
33+
/// - Parameter advance: The glyph advance.
34+
/// - Parameter offset: The glyph offset.
35+
/// - Parameter bearing: The glyph bearing.
36+
/// - Parameter size: The glyph size.
37+
/// - Parameter uv: The glyph UV coordinates.
38+
init(index: UInt32 = 0, advance: Point3D = .zero, offset: Point3D = .zero, bearing: Point3D = .zero, size: Size3D = .zero, uv: (u0: Double, v0: Double, u1: Double, v1: Double) = (0, 0, 0, 0)) {
39+
self.index = index
40+
self.advance = advance
41+
self.offset = offset
42+
self.bearing = bearing
43+
self.size = size
44+
self.uv = uv
45+
}
4946

50-
extension Font.Glyph : Hashable {
47+
/// Checks if two glyphs are equal.
48+
///
49+
/// - Parameter lhs: The left glyph.
50+
/// - Parameter rhs: The right glyph.
51+
/// - Returns: `true` if the glyphs are equal, `false` otherwise.
52+
static func == (lhs: Font.Glyph, rhs: Font.Glyph) -> Bool {
53+
lhs.index == rhs.index && lhs.advance == rhs.advance && lhs.offset == rhs.offset && lhs.bearing == rhs.bearing && lhs.size == rhs.size && lhs.uv == rhs.uv
54+
}
5155

52-
/// Hashes the glyph into the given hash.
53-
///
54-
/// - Parameter hasher: The hasher to hash the glyph into.
55-
func hash(into hasher: inout Hasher) {
56-
hasher.combine(index)
57-
hasher.combine(advance)
58-
hasher.combine(offset)
59-
hasher.combine(bearing)
60-
hasher.combine(size)
61-
hasher.combine(uv.u0)
62-
hasher.combine(uv.v0)
63-
hasher.combine(uv.u1)
64-
hasher.combine(uv.v1)
56+
/// Hashes the glyph into the given hasher.
57+
///
58+
/// - Parameter hasher: The hasher to hash the glyph into.
59+
func hash(into hasher: inout Hasher) {
60+
hasher.combine(index)
61+
hasher.combine(advance)
62+
hasher.combine(offset)
63+
hasher.combine(bearing)
64+
hasher.combine(size)
65+
hasher.combine(uv.u0)
66+
hasher.combine(uv.v0)
67+
hasher.combine(uv.u1)
68+
hasher.combine(uv.v1)
69+
}
6570
}
6671
}

0 commit comments

Comments
 (0)