From 1a380db8612b78a133cb4b60fbaad424dcd684ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Nyg=C3=A5rd?= Date: Wed, 9 Sep 2026 10:14:54 +0200 Subject: [PATCH] Fix graphics scaling and add window-filling previews --- QuickMD/QuickMD/BlockHeightMeasurer.swift | 6 ++ QuickMD/QuickMD/MarkdownView.swift | 24 ++++- .../QuickMD/Resources/mermaid-template.html | 32 +++++- QuickMD/QuickMD/Views/ImageBlockView.swift | 102 ++++++++++++++---- QuickMD/QuickMD/Views/MermaidBlockView.swift | 63 +++++++---- .../BlockHeightMeasurerTests.swift | 9 ++ QuickMD/test-image-scaling.md | 65 +++++++++++ scripts/check-mermaid-scaling.swift | 67 ++++++++++++ 8 files changed, 321 insertions(+), 47 deletions(-) create mode 100644 QuickMD/test-image-scaling.md create mode 100644 scripts/check-mermaid-scaling.swift diff --git a/QuickMD/QuickMD/BlockHeightMeasurer.swift b/QuickMD/QuickMD/BlockHeightMeasurer.swift index bc7a513..621884a 100644 --- a/QuickMD/QuickMD/BlockHeightMeasurer.swift +++ b/QuickMD/QuickMD/BlockHeightMeasurer.swift @@ -248,6 +248,12 @@ enum BlockLayout { /// the bitmap is decoded, so this is what a measured row starts at. static let placeholderHeight: CGFloat = 100 static let maxDisplayWidth: CGFloat = 600 + + /// Scale the fitted 100% width, then keep the result inside the column. + static func displayWidth(fontScale: CGFloat, contentWidth: CGFloat) -> CGFloat { + let available = max(1, contentWidth) + return min(available, min(maxDisplayWidth, available) * fontScale) + } } // MARK: Display math diff --git a/QuickMD/QuickMD/MarkdownView.swift b/QuickMD/QuickMD/MarkdownView.swift index 63c4d35..e612a5e 100644 --- a/QuickMD/QuickMD/MarkdownView.swift +++ b/QuickMD/QuickMD/MarkdownView.swift @@ -46,6 +46,7 @@ struct MarkdownView: View { @State private var currentMatchIndex: Int = 0 @State private var matchBlockIds: [String] = [] @State private var scrollTrigger: Int = 0 + @State private var graphicPreview: GraphicPreview? @State private var keyMonitor: Any? /// The NSWindow hosting this view (set by `WindowConfigurator`); the key /// monitor uses it to ignore events addressed to other tabs' windows. @@ -362,6 +363,13 @@ struct MarkdownView: View { /// modifier chain no longer type-checks inside the compiler's budget. private var configuredDocumentStack: some View { documentStack + .disabled(graphicPreview != nil) + .accessibilityHidden(graphicPreview != nil) + .overlay { + if let graphicPreview { + GraphicPreviewOverlay(preview: graphicPreview) { self.graphicPreview = nil } + } + } .background(theme.backgroundColor) .background(WindowConfigurator { window in // Make every QuickMD document window prefer to join existing windows @@ -557,6 +565,13 @@ struct MarkdownView: View { if let hostWindow, let eventWindow = event.window, eventWindow !== hostWindow { return event } + if graphicPreview != nil { + if event.keyCode == 53 { + graphicPreview = nil + return nil + } + return event + } let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask) if flags.contains(.command) && event.charactersIgnoringModifiers == "g" { @@ -680,7 +695,9 @@ struct MarkdownView: View { .padding(.vertical, Metrics.codeOuterVerticalPadding) case .image(let url, let alt): - ImageBlockView(url: url, alt: alt, theme: theme, documentURL: documentURL) + ImageBlockView(url: url, alt: alt, theme: theme, documentURL: documentURL, + fontScale: scale, contentWidth: contentWidth, + onEnlarge: { graphicPreview = $0 }) .padding(.vertical, Metrics.imageOuterVerticalPadding) case .blockquote(let content, let level): @@ -721,7 +738,10 @@ struct MarkdownView: View { case .mermaidDiagram(let source): MermaidBlockView(blockId: block.id, source: source, theme: theme, - heightCache: heightCache) + heightCache: heightCache, fontScale: scale, + contentWidth: contentWidth, + onEnlarge: { graphicPreview = $0 }) + .id("\(block.id)|\(scale)|\(contentWidth)|\(theme.isDark)") .padding(.vertical, Metrics.mermaidOuterVerticalPadding) } } diff --git a/QuickMD/QuickMD/Resources/mermaid-template.html b/QuickMD/QuickMD/Resources/mermaid-template.html index e820146..bc18e24 100644 --- a/QuickMD/QuickMD/Resources/mermaid-template.html +++ b/QuickMD/QuickMD/Resources/mermaid-template.html @@ -13,7 +13,12 @@