diff --git a/app/src/main/java/org/fairscan/app/platform/AndroidPdfWriter.kt b/app/src/main/java/org/fairscan/app/platform/AndroidPdfWriter.kt index d4d94a5..6cd2769 100644 --- a/app/src/main/java/org/fairscan/app/platform/AndroidPdfWriter.kt +++ b/app/src/main/java/org/fairscan/app/platform/AndroidPdfWriter.kt @@ -46,12 +46,12 @@ class AndroidPdfWriter : PdfWriter { val dimensions = page.estimatedDimensions() val (widthMm, heightMm) = when (dimensions) { is EstimatedDimensions.Physical -> - clipToMaxFormat(dimensions.widthMm, dimensions.heightMm) + constrainToMaxFormat(dimensions.widthMm, dimensions.heightMm) else -> { // No physical dimensions available val maxDimMm = PaperFormats.A4.heightMm val scalePxToMm = maxDimMm / maxOf(widthPx, heightPx) - clipToMaxFormat(widthPx * scalePxToMm, heightPx * scalePxToMm) + constrainToMaxFormat(widthPx * scalePxToMm, heightPx * scalePxToMm) } } val widthPoints = widthMm.toFloat() * pointsPerMm @@ -71,13 +71,14 @@ class AndroidPdfWriter : PdfWriter { } } -fun clipToMaxFormat(widthMm: Double, heightMm: Double): Pair { - // Normalize to portrait for comparison - val (w, h) = if (widthMm <= heightMm) widthMm to heightMm else heightMm to widthMm - val portrait = widthMm <= heightMm +fun constrainToMaxFormat(widthMm: Double, heightMm: Double): Pair { + val maxDim = 297.0 // A4 height + val minDim = 215.9 // Letter width - val maxFormat = PaperFormats.A4 - val scale = minOf(maxFormat.widthMm / w, maxFormat.heightMm / h, 1.0) - val clipped = w * scale to h * scale - return if (portrait) clipped else clipped.second to clipped.first + val scale = minOf( + maxDim / maxOf(widthMm, heightMm), + minDim / minOf(widthMm, heightMm), + 1.0 + ) + return widthMm * scale to heightMm * scale } diff --git a/app/src/test/java/org/fairscan/app/platform/AndroidPdfWriterTest.kt b/app/src/test/java/org/fairscan/app/platform/AndroidPdfWriterTest.kt index 62cdf75..603b328 100644 --- a/app/src/test/java/org/fairscan/app/platform/AndroidPdfWriterTest.kt +++ b/app/src/test/java/org/fairscan/app/platform/AndroidPdfWriterTest.kt @@ -21,36 +21,42 @@ import org.junit.Test class AndroidPdfWriterTest { @Test fun `portrait smaller than A4 is unchanged`() { - val (w, h) = clipToMaxFormat(100.0, 150.0) + val (w, h) = constrainToMaxFormat(100.0, 150.0) assertThat(w).isEqualTo(100.0) assertThat(h).isEqualTo(150.0) } - @Test fun `portrait taller than A4 is clipped preserving ratio`() { - val (w, h) = clipToMaxFormat(210.0, 400.0) + @Test fun `portrait taller than A4 is constrained preserving ratio`() { + val (w, h) = constrainToMaxFormat(210.0, 400.0) assertThat(h).isCloseTo(297.0, offset(0.1)) assertThat(w / h).isCloseTo(210.0 / 400.0, offset(0.001)) } - @Test fun `landscape wider than A4 is clipped preserving ratio`() { - val (w, h) = clipToMaxFormat(300.0, 200.0) + @Test fun `landscape wider than A4 is constrained preserving ratio`() { + val (w, h) = constrainToMaxFormat(300.0, 200.0) assertThat(w).isCloseTo(297.0, offset(0.1)) assertThat(w / h).isCloseTo(300.0 / 200.0, offset(0.001)) } @Test fun `exactly A4 is unchanged`() { - val (w, h) = clipToMaxFormat(210.0, 297.0) + val (w, h) = constrainToMaxFormat(210.0, 297.0) assertThat(w).isCloseTo(210.0, offset(0.001)) assertThat(h).isCloseTo(297.0, offset(0.001)) } - @Test fun `landscape orientation is preserved after clip`() { - val (w, h) = clipToMaxFormat(400.0, 250.0) + @Test fun `exactly Letter is unchanged`() { + val (w, h) = constrainToMaxFormat(215.9, 279.4) + assertThat(w).isCloseTo(215.9, offset(0.001)) + assertThat(h).isCloseTo(279.4, offset(0.001)) + } + + @Test fun `landscape orientation is preserved`() { + val (w, h) = constrainToMaxFormat(400.0, 250.0) assertThat(w).isGreaterThan(h) } @Test fun `landscape smaller than A4 is unchanged`() { - val (w, h) = clipToMaxFormat(297.0, 150.0) + val (w, h) = constrainToMaxFormat(297.0, 150.0) assertThat(w).isCloseTo(297.0, offset(0.001)) assertThat(h).isCloseTo(150.0, offset(0.001)) }