Skip to content

Refactor: extract thumbnail aspect-fit math into ThumbnailGeometry#10

Merged
GamalAnwar merged 1 commit into
masterfrom
claude/solid-refactor-thumbnail-geometry
Jun 18, 2026
Merged

Refactor: extract thumbnail aspect-fit math into ThumbnailGeometry#10
GamalAnwar merged 1 commit into
masterfrom
claude/solid-refactor-thumbnail-geometry

Conversation

@GamalAnwar

Copy link
Copy Markdown
Contributor

Summary

Slice 1 of 2 (the JPEG/thumbnail path). CaptureManager.saveJPEGThumbnail computed the scaled thumbnail size inline — min-of-ratios, clamped to 1.0 (never upscale), guarded for non-positive input — interleaved with the NSImage drawing. This lifts the pure geometry into:

ThumbnailGeometry.fittedSize(for: image.size, maxDimension: 320)

so the aspect-fit rule is testable without any AppKit drawing. The drawing code stays put and just consumes the computed size.

Scope / safety

  • Behavior-preserving. Same min(maxDim/w, maxDim/h, 1.0) math; the non-positive guard now reads guard thumbSize.width > 0 (fittedSize returns .zero for non-positive input), identical effect to the old guard w > 0, h > 0.
  • saveJPEG itself (the NSBitmapImageRep → JPEG encoder shared by full-size save and thumbnail) is unchanged.

Tests

ThumbnailGeometryTests (6 cases): landscape fits to width, portrait fits to height, never upscales, aspect ratio preserved + within box, zero/negative → .zero, square scales uniformly.

🤖 Generated with Claude Code


Generated by Claude Code

CaptureManager.saveJPEGThumbnail computed the scaled thumbnail size inline
(min-of-ratios, clamped to 1.0, guarded for non-positive input). Move that into
a pure ThumbnailGeometry.fittedSize(for:maxDimension:) so the rule is testable
without AppKit drawing. Behavior-preserving. Adds ThumbnailGeometryTests (6 cases).
@GamalAnwar GamalAnwar merged commit 17d9741 into master Jun 18, 2026
1 check passed
@GamalAnwar GamalAnwar deleted the claude/solid-refactor-thumbnail-geometry branch June 18, 2026 07:36
GamalAnwar pushed a commit that referenced this pull request Jun 18, 2026
… NSImage.encoded

EditorView.writeImageSync chose PNG vs JPEG-0.9 by file extension and inlined
both encoders; the JPEG branch duplicated CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail duplicated both the JPEG encoder and the
thumbnail sizing math (the latter already extracted as ThumbnailGeometry in #10).

Add ImageExportFormat (.png / .jpeg(quality), plus .forPath(_:) extension
decision) and a single NSImage.encoded(as:) encoder. Rewire all three call sites:
EditorView.writeImageSync, CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail (now also using ThumbnailGeometry).

Behavior-preserving. Adds ImageExportFormatTests (8 cases) covering the path
decision and PNG/JPEG signatures of the encoded data.
GamalAnwar added a commit that referenced this pull request Jun 18, 2026
Lift CaptureManager.saveJPEGThumbnail's inline aspect-fit math (min-of-ratios,
clamp to 1.0, non-positive guard) into a pure ThumbnailGeometry.fittedSize(
for:maxDimension:). Behavior-preserving. Adds ThumbnailGeometryTests (6 cases).
CI green.
GamalAnwar pushed a commit that referenced this pull request Jun 18, 2026
… NSImage.encoded

EditorView.writeImageSync chose PNG vs JPEG-0.9 by file extension and inlined
both encoders; the JPEG branch duplicated CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail duplicated both the JPEG encoder and the
thumbnail sizing math (the latter already extracted as ThumbnailGeometry in #10).

Add ImageExportFormat (.png / .jpeg(quality), plus .forPath(_:) extension
decision) and a single NSImage.encoded(as:) encoder. Rewire all three call sites:
EditorView.writeImageSync, CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail (now also using ThumbnailGeometry).

Behavior-preserving. Adds ImageExportFormatTests (8 cases) covering the path
decision and PNG/JPEG signatures of the encoded data.
GamalAnwar added a commit that referenced this pull request Jun 18, 2026
… NSImage.encoded

EditorView.writeImageSync chose PNG vs JPEG-0.9 by file extension and inlined
both encoders; the JPEG branch duplicated CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail duplicated both the JPEG encoder and the
thumbnail sizing math (the latter already extracted as ThumbnailGeometry in #10).

Add ImageExportFormat (.png / .jpeg(quality), plus .forPath(_:) extension
decision) and a single NSImage.encoded(as:) encoder. Rewire all three call sites:
EditorView.writeImageSync, CaptureManager.saveJPEG, and
CaptureHistoryStore.writeThumbnail (now also using ThumbnailGeometry).

Behavior-preserving. Adds ImageExportFormatTests (8 cases) covering the path
decision and PNG/JPEG signatures of the encoded data.
GamalAnwar added a commit that referenced this pull request Jun 18, 2026
Lift CaptureManager.saveJPEGThumbnail's inline aspect-fit math (min-of-ratios,
clamp to 1.0, non-positive guard) into a pure ThumbnailGeometry.fittedSize(
for:maxDimension:). Behavior-preserving. Adds ThumbnailGeometryTests (6 cases).
CI green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants