diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/text/DelegatingSubtitleDecoderTtmlParserTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/text/DelegatingSubtitleDecoderTtmlParserTest.java
index cc2a942d83..adf392fc11 100644
--- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/text/DelegatingSubtitleDecoderTtmlParserTest.java
+++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/text/DelegatingSubtitleDecoderTtmlParserTest.java
@@ -505,8 +505,8 @@ public final class DelegatingSubtitleDecoderTtmlParserTest {
Cue cue = getOnlyCueAtTimeUs(subtitle, 1_000_000);
assertThat(cue.text).isNull();
assertThat(cue.bitmap).isNotNull();
- assertThat(cue.position).isEqualTo(24f / 100f);
- assertThat(cue.line).isEqualTo(28f / 100f);
+ assertThat(cue.position).isEqualTo(-24.2f / 100f);
+ assertThat(cue.line).isEqualTo(28.5f / 100f);
assertThat(cue.size).isEqualTo(51f / 100f);
assertThat(cue.bitmapHeight).isEqualTo(12f / 100f);
@@ -521,8 +521,8 @@ public final class DelegatingSubtitleDecoderTtmlParserTest {
cue = getOnlyCueAtTimeUs(subtitle, 7_500_000);
assertThat(cue.text).isNull();
assertThat(cue.bitmap).isNotNull();
- assertThat(cue.position).isEqualTo(24f / 100f);
- assertThat(cue.line).isEqualTo(28f / 100f);
+ assertThat(cue.position).isEqualTo(-24.2f / 100f);
+ assertThat(cue.line).isEqualTo(28.5f / 100f);
assertThat(cue.size).isEqualTo(51f / 100f);
assertThat(cue.bitmapHeight).isEqualTo(12f / 100f);
}
@@ -534,7 +534,7 @@ public final class DelegatingSubtitleDecoderTtmlParserTest {
Cue cue = getOnlyCueAtTimeUs(subtitle, 1_000_000);
assertThat(cue.text).isNull();
assertThat(cue.bitmap).isNotNull();
- assertThat(cue.position).isEqualTo(307f / 1280f);
+ assertThat(cue.position).isEqualTo(-307f / 1280f);
assertThat(cue.line).isEqualTo(562f / 720f);
assertThat(cue.size).isEqualTo(653f / 1280f);
assertThat(cue.bitmapHeight).isEqualTo(86f / 720f);
diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java
index d1e42f118c..d1d615657a 100644
--- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java
+++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/ttml/TtmlParser.java
@@ -105,9 +105,9 @@ public final class TtmlParser implements SubtitleParser {
private static final Pattern FONT_SIZE = Pattern.compile("^(([0-9]*.)?[0-9]+)(px|em|%)$");
static final Pattern SIGNED_PERCENTAGE = Pattern.compile("^([-+]?\\d+\\.?\\d*?)%$");
static final Pattern PERCENTAGE_COORDINATES =
- Pattern.compile("^(\\d+\\.?\\d*?)% (\\d+\\.?\\d*?)%$");
+ Pattern.compile("^([-+]?\\d+\\.?\\d*?)% ([-+]?\\d+\\.?\\d*?)%$");
private static final Pattern PIXEL_COORDINATES =
- Pattern.compile("^(\\d+\\.?\\d*?)px (\\d+\\.?\\d*?)px$");
+ Pattern.compile("^([-+]?\\d+\\.?\\d*?)px ([-+]?\\d+\\.?\\d*?)px$");
private static final Pattern CELL_RESOLUTION = Pattern.compile("^(\\d+) (\\d+)$");
private static final int DEFAULT_FRAME_RATE = 30;
diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/text/ttml/TtmlParserTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/text/ttml/TtmlParserTest.java
index 08945d44d7..38cee01100 100644
--- a/libraries/extractor/src/test/java/androidx/media3/extractor/text/ttml/TtmlParserTest.java
+++ b/libraries/extractor/src/test/java/androidx/media3/extractor/text/ttml/TtmlParserTest.java
@@ -693,8 +693,8 @@ public final class TtmlParserTest {
Cue cue = Iterables.getOnlyElement(allCues.get(0).cues);
assertThat(cue.text).isNull();
assertThat(cue.bitmap).isNotNull();
- assertThat(cue.position).isEqualTo(24f / 100f);
- assertThat(cue.line).isEqualTo(28f / 100f);
+ assertThat(cue.position).isEqualTo(-24.2f / 100f);
+ assertThat(cue.line).isEqualTo(28.5f / 100f);
assertThat(cue.size).isEqualTo(51f / 100f);
assertThat(cue.bitmapHeight).isEqualTo(12f / 100f);
@@ -713,8 +713,8 @@ public final class TtmlParserTest {
cue = Iterables.getOnlyElement(allCues.get(2).cues);
assertThat(cue.text).isNull();
assertThat(cue.bitmap).isNotNull();
- assertThat(cue.position).isEqualTo(24f / 100f);
- assertThat(cue.line).isEqualTo(28f / 100f);
+ assertThat(cue.position).isEqualTo(-24.2f / 100f);
+ assertThat(cue.line).isEqualTo(28.5f / 100f);
assertThat(cue.size).isEqualTo(51f / 100f);
assertThat(cue.bitmapHeight).isEqualTo(12f / 100f);
}
@@ -730,7 +730,7 @@ public final class TtmlParserTest {
Cue cue = Iterables.getOnlyElement(allCues.get(0).cues);
assertThat(cue.text).isNull();
assertThat(cue.bitmap).isNotNull();
- assertThat(cue.position).isEqualTo(307f / 1280f);
+ assertThat(cue.position).isEqualTo(-307f / 1280f);
assertThat(cue.line).isEqualTo(562f / 720f);
assertThat(cue.size).isEqualTo(653f / 1280f);
assertThat(cue.bitmapHeight).isEqualTo(86f / 720f);
diff --git a/libraries/test_data/src/test/assets/media/ttml/bitmap_percentage_region.xml b/libraries/test_data/src/test/assets/media/ttml/bitmap_percentage_region.xml
index 9631650178..26d447ce83 100644
--- a/libraries/test_data/src/test/assets/media/ttml/bitmap_percentage_region.xml
+++ b/libraries/test_data/src/test/assets/media/ttml/bitmap_percentage_region.xml
@@ -14,8 +14,8 @@