feat(printing): add print font scaling options and document-proportional clean print theme sizing

This commit is contained in:
james.maes committed 2026-07-24 08:28:58 -05:00
1 parent 0d1133aafd
commit 1ab16bf4ed
4 files changed
+63 -5

No files matched your search

+20 -1
View File
@@ -278,7 +278,7 @@ struct ContentView: View {
}
// Determine zoom scale based on print settings
let zoom = printZoom == "Match Screen" ? zoomScale : 1.0
let zoom = PrintZoomResolver.zoomScale(for: printZoom, screenZoom: zoomScale)
let printCSS = themeToPrint != nil ? themeManager.generateCSS(for: themeToPrint!, zoomScale: zoom) : ""
let escapedPrintCSS = printCSS.escapedForJavaScriptLiteral()
@@ -1229,3 +1229,22 @@ fileprivate extension String {
.replacingOccurrences(of: "\n", with: "\\n")
}
}
enum PrintZoomResolver {
static func zoomScale(for printZoom: String, screenZoom: Double) -> Double {
switch printZoom {
case "Compact (75%)":
return 0.75
case "Small (85%)":
return 0.85
case "Standard (100%)":
return 1.0
case "Large (115%)":
return 1.15
case "Match Screen":
return screenZoom
default:
return 1.0
}
}
}
+7 -3
View File
@@ -581,17 +581,21 @@ struct PrintingSettingsView: View {
GroupBox(label: Text("Zoom & Scaling")) {
VStack(alignment: .leading, spacing: 12) {
HStack {
Text("Font Zoom")
Text("Font Scaling")
Spacer()
Picker("Font Zoom", selection: $printZoom) {
Picker("Font Scaling", selection: $printZoom) {
Text("Compact (75%)").tag("Compact (75%)")
Text("Small (85%)").tag("Small (85%)")
Text("Standard (100%)").tag("Standard (100%)")
Text("Large (115%)").tag("Large (115%)")
Divider()
Text("Match Screen").tag("Match Screen")
}
.frame(width: 200)
.labelsHidden()
}
Text("Select whether the printed document inherits the screen zoom scaling.")
Text("Select the scale for printed document fonts, or match current screen zoom.")
.font(.caption)
.foregroundStyle(.secondary)
+11 -1
View File
@@ -194,7 +194,17 @@ extension Theme {
highlightText: "#24292e"
),
fonts: ThemeFonts(body: "System", heading: "System", code: "SF Mono"),
sizes: ThemeSizes(),
sizes: ThemeSizes(
baseFontSize: 11,
h1Size: 22,
h2Size: 18,
h3Size: 15,
h4Size: 13.5,
h5Size: 12,
h6Size: 11,
codeFontSize: 10.5,
lineHeight: 1.5
),
customCSS: "",
isBuiltIn: true
)
+25
View File
@@ -310,6 +310,31 @@ final class PrintingTests: XCTestCase {
XCTAssertTrue(plainScript.contains("document.getElementById('theme-css').textContent = ''"))
}
func testPrintZoomResolver() {
XCTAssertEqual(PrintZoomResolver.zoomScale(for: "Compact (75%)", screenZoom: 1.5), 0.75)
XCTAssertEqual(PrintZoomResolver.zoomScale(for: "Small (85%)", screenZoom: 1.5), 0.85)
XCTAssertEqual(PrintZoomResolver.zoomScale(for: "Standard (100%)", screenZoom: 1.5), 1.0)
XCTAssertEqual(PrintZoomResolver.zoomScale(for: "Large (115%)", screenZoom: 1.5), 1.15)
XCTAssertEqual(PrintZoomResolver.zoomScale(for: "Match Screen", screenZoom: 1.5), 1.5)
XCTAssertEqual(PrintZoomResolver.zoomScale(for: "Unknown", screenZoom: 1.5), 1.0)
}
func testCleanPrintingThemeUsesPrintProportionalFontSizes() {
let sizes = Theme.cleanPrinting.sizes
XCTAssertLessThanOrEqual(sizes.baseFontSize, 12.0)
XCTAssertLessThanOrEqual(sizes.h1Size, 22.0)
XCTAssertLessThanOrEqual(sizes.h2Size, 18.0)
XCTAssertLessThanOrEqual(sizes.codeFontSize, 11.0)
}
func testSettingsViewIncludesExpandedFontScalingOptions() throws {
let settingsSource = try loadSourceFile("markdownViewr/SettingsView.swift")
XCTAssertTrue(settingsSource.contains(#"Text("Compact (75%)").tag("Compact (75%)")"#))
XCTAssertTrue(settingsSource.contains(#"Text("Small (85%)").tag("Small (85%)")"#))
XCTAssertTrue(settingsSource.contains(#"Text("Standard (100%)").tag("Standard (100%)")"#))
XCTAssertTrue(settingsSource.contains(#"Text("Large (115%)").tag("Large (115%)")"#))
}
// 4. Functional test for PrintCoordinator script building and memory cycles
@MainActor
func testPrintCoordinatorMemoryManagementAndRestore() {