Merge "Update test case for the platform that has letter spacing fix" into androidx-main
diff --git a/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTest.kt b/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTest.kt
index 1504032..9a40fca 100644
--- a/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTest.kt
+++ b/compose/ui/ui-text/src/androidInstrumentedTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTest.kt
@@ -75,6 +75,26 @@
 
     private val resourceLoader = UncachedFontFamilyResolver(context)
 
+    private fun hasEdgeLetterSpacingBugFix(): Boolean {
+        val text = "a"
+        val fontSize = 10.sp
+        val singleLetterLetterSpacing = simpleParagraph(
+            text = text,
+            style = TextStyle(fontSize = fontSize, letterSpacing = 10.sp),
+            width = Float.MAX_VALUE)
+
+        val singleLetterWithoutLetterSpacing = simpleParagraph(
+            text = text,
+            style = TextStyle(fontSize = fontSize),
+            width = Float.MAX_VALUE)
+
+        // If the platform has a letter spacing fix, the letter spacing will not be added before and
+        // after the visually left most letter and visually right most letter. Therefore, if the fix
+        // is available, the letter spacing is no-op for single letter text.
+        return singleLetterLetterSpacing.getLineWidth(0) ==
+            singleLetterWithoutLetterSpacing.getLineWidth(0)
+    }
+
     @Test
     fun empty_string() {
         with(defaultDensity) {
@@ -3361,8 +3381,16 @@
 
             assertThat(paragraph.lineCount).isEqualTo(1)
             // Notice that in this test font, the width of character equals to fontSize.
-            assertThat(paragraph.getLineWidth(0))
-                .isEqualTo(fontSizeInPx * text.length * (1 + letterSpacing))
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(fontSizeInPx * text.length * (1 + letterSpacing) -
+                        fontSizeInPx * letterSpacing * 0.5f - // left edge letter spacing
+                        fontSizeInPx * letterSpacing * 0.5f // right edge letter spacing
+                    )
+            } else {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(fontSizeInPx * text.length * (1 + letterSpacing))
+            }
         }
     }
 
@@ -3384,8 +3412,15 @@
 
             assertThat(paragraph.lineCount).isEqualTo(1)
             // Notice that in this test font, the width of character equals to fontSize.
-            assertThat(paragraph.getLineWidth(0))
-                .isEqualTo((fontSizeInPx + letterSpacing) * text.length)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo((fontSizeInPx + letterSpacing) * text.length -
+                        letterSpacing * 0.5f - // left edge letter spacing
+                        letterSpacing * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo((fontSizeInPx + letterSpacing) * text.length)
+            }
         }
     }
 
@@ -3408,7 +3443,14 @@
             assertThat(paragraph.lineCount).isEqualTo(1)
             // Notice that in this test font, the width of character equals to fontSize.
             val expectedWidth = ("abc".length * letterSpacing + text.length) * fontSizeInPx
-            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(expectedWidth -
+                        letterSpacing * fontSizeInPx * 0.5f - // left edge letter spacing
+                        0f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            }
         }
     }
 
@@ -3438,7 +3480,14 @@
             // Notice that in this test font, the width of character equals to fontSize.
             val expectedWidth = "abc".length * (1 + letterSpacingOverwrite) * fontSizeInPx +
                 "de".length * (1 + letterSpacing) * fontSizeInPx
-            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(expectedWidth -
+                        fontSizeInPx * letterSpacingOverwrite * 0.5f - // left edge letter spacing
+                        fontSizeInPx * letterSpacing * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            }
         }
     }
 
@@ -3470,7 +3519,14 @@
             // Notice that in this test font, the width of character equals to fontSize.
             val expectedWidth = (1 + letterSpacing) *
                 ("abc".length * fontSizeOverwriteInPx + "de".length * fontSizeInPx)
-            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(expectedWidth -
+                        letterSpacing * fontSizeOverwriteInPx * 0.5f - // left edge letter spacing
+                        letterSpacing * fontSizeInPx * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            }
         }
     }
 
@@ -3501,7 +3557,14 @@
             // Notice that in this test font, the width of character equals to fontSize.
             val expectedWidth = (1 + letterSpacing) *
                 ("abc".length * fontSizeInPx * scaleX + "de".length * fontSizeInPx)
-            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(expectedWidth -
+                        letterSpacing * fontSizeInPx * scaleX * 0.5f - // left edge letter spacing
+                        letterSpacing * fontSizeInPx * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            }
         }
     }
 
@@ -3534,7 +3597,14 @@
             // Notice that in this test font, the width of character equals to fontSize.
             val expectedWidth = text.length * letterSpacingInPx +
                 ("abc".length * fontSizeOverwriteInPx + "de".length * fontSizeInPx)
-            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(expectedWidth -
+                        letterSpacingInPx * 0.5f - // left edge letter spacing
+                        letterSpacingInPx * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            }
         }
     }
 
@@ -3566,7 +3636,14 @@
             // Notice that in this test font, the width of character equals to fontSize.
             val expectedWidth = text.length * letterSpacingInPx +
                 ("abc".length * fontSizeInPx * scaleX + "de".length * fontSizeInPx)
-            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineWidth(0))
+                    .isEqualTo(expectedWidth -
+                        letterSpacingInPx * 0.5f - // left edge letter spacing
+                        letterSpacingInPx * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+            }
         }
     }
 
@@ -3595,7 +3672,14 @@
         // Notice that in this test font, the width of character equals to fontSize.
         val expectedWidth = fontSize * text.length + "abc".length * letterSpacingSp +
             "de".length * fontSize * letterSpacingEm
-        assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+        if (hasEdgeLetterSpacingBugFix()) {
+            assertThat(paragraph.getLineWidth(0))
+                .isEqualTo(expectedWidth -
+                    letterSpacingSp * 0.5f - // left edge letter spacing
+                    fontSize * letterSpacingEm * 0.5f) // right edge letter spacing
+        } else {
+            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+        }
     }
 
     @Test
@@ -3622,7 +3706,14 @@
         assertThat(paragraph.lineCount).isEqualTo(1)
         // Notice that in this test font, the width of character equals to fontSize.
         val expectedWidth = fontSize * text.length * (1 + letterSpacingEm)
-        assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+        if (hasEdgeLetterSpacingBugFix()) {
+            assertThat(paragraph.getLineWidth(0))
+                .isEqualTo(expectedWidth -
+                    letterSpacingEm * fontSize * 0.5f - // left edge letter spacing
+                    letterSpacingEm * fontSize * 0.5f) // right edge letter spacing
+        } else {
+            assertThat(paragraph.getLineWidth(0)).isEqualTo(expectedWidth)
+        }
     }
 
     @Test
@@ -3891,8 +3982,15 @@
                 )
             )
 
-            assertThat(paragraph.getLineRight(0))
-                .isEqualTo(fontSizeInPx * (1 + letterSpacing) * text.length)
+            if (hasEdgeLetterSpacingBugFix()) {
+                assertThat(paragraph.getLineRight(0))
+                    .isEqualTo(fontSizeInPx * (1 + letterSpacing) * text.length -
+                        fontSizeInPx * 0.5f - // left edge letter spacing
+                        fontSizeInPx * 0.5f) // right edge letter spacing
+            } else {
+                assertThat(paragraph.getLineRight(0))
+                    .isEqualTo(fontSizeInPx * (1 + letterSpacing) * text.length)
+            }
         }
     }