oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1import Foundation
2import Testing
3@testable import DocsKit
4#if os(macOS)
5import AppKit
6#else
7import UIKit
8#endif
9
10@Test func letterGeometryAndNarrowReflow() {
11 let desktop = DocsPageGeometry(viewportWidth: 800, paged: true)
12 #expect(desktop.paperWidth == 612)
13 #expect(desktop.textWidth == 468)
14 #expect(desktop.bodyHeight == 648)
15 let phone = DocsPageGeometry(viewportWidth: 320, paged: true)
16 #expect(phone.textWidth >= 256)
17 let crossing = desktop.lineRect(CGRect(x: 0, y: 710, width: 800, height: 20))
18 #expect(crossing.minY == 888)
19 let continuous = DocsPageGeometry(viewportWidth: 800, paged: false)
20 #expect(continuous.lineRect(CGRect(x: 0, y: 710, width: 800, height: 20)).minY == 710)
21}
22
23@MainActor @Test func nativePaginationMovesGlyphsWithoutChangingTextOffsets() {
24 let source = String(repeating: "Wrapped text العربية 日本語 🧪 preserves offsets. ", count: 100)
25 + "\n" + String(repeating: "Native paging preserves every character and edit offset.\n", count: 100)
26 let storage = NSTextStorage(string: source)
27 #if os(macOS)
28 storage.addAttribute(.font, value: NSFont.systemFont(ofSize: 12), range: NSRange(location: 0, length: storage.length))
29 #else
30 storage.addAttribute(.font, value: UIFont.systemFont(ofSize: 12), range: NSRange(location: 0, length: storage.length))
31 #endif
32 let manager = NSLayoutManager()
33 let container = DocsPageTextContainer(size: CGSize(width: 800, height: 1_000_000))
34 container.lineFragmentPadding = 0
35 container.geometry = DocsPageGeometry(viewportWidth: 800, paged: true)
36 storage.addLayoutManager(manager)
37 manager.addTextContainer(container)
38 manager.ensureLayout(for: container)
39 var secondPageGlyph: Int?
40 manager.enumerateLineFragments(forGlyphRange: NSRange(location: 0, length: manager.numberOfGlyphs)) { rect, _, _, glyphs, _ in
41 let page = container.geometry.page(at: rect.minY)
42 let top = CGFloat(page) * container.geometry.stride + DocsPageGeometry.verticalMargin
43 #expect(rect.minY >= top)
44 #expect(rect.maxY <= top + container.geometry.bodyHeight + 0.1)
45 #expect(rect.minX >= container.geometry.textX)
46 #expect(rect.maxX <= container.geometry.textX + container.geometry.textWidth + 0.1)
47 if page > 0 && secondPageGlyph == nil { secondPageGlyph = glyphs.location }
48 }
49 #expect(secondPageGlyph != nil)
50 #expect(storage.string == source)
51 let location = manager.characterIndexForGlyph(at: secondPageGlyph ?? 0)
52 #expect(location > 0 && location < source.utf16.count)
53 storage.replaceCharacters(in: NSRange(location: location, length: 0), with: "🧪")
54 #expect((storage.string as NSString).substring(with: NSRange(location: location, length: 2)) == "🧪")
55 container.geometry.paged = false
56 manager.ensureLayout(for: container)
57 #expect(storage.length == source.utf16.count + 2)
58}
59