diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java
index 51d4caa268..4d6e9b7227 100644
--- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java
+++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java
@@ -69,7 +69,6 @@
import org.jellyfin.androidtv.ui.presentation.CardPresenter;
import org.jellyfin.androidtv.ui.presentation.ChannelCardPresenter;
import org.jellyfin.androidtv.ui.presentation.PositionableListRowPresenter;
-import org.jellyfin.androidtv.ui.shared.OutlineSpan;
import org.jellyfin.androidtv.ui.shared.PaddedLineBackgroundSpan;
import org.jellyfin.androidtv.util.DeviceUtils;
import org.jellyfin.androidtv.util.ImageUtils;
@@ -1467,11 +1466,11 @@ private void renderSubtitles(@Nullable final String text) {
.replaceAll("\\\\h", " ");
final SpannableString span = new SpannableString(TextUtilsKt.toHtmlSpanned(htmlText));
- span.setSpan(new ForegroundColorSpan(Color.WHITE), 0, span.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (subtitlesBackgroundEnabled) {
+ // Disable the text outlining when the background is enabled
+ binding.subtitlesText.setStrokeWidth(0.0f);
span.setSpan(new PaddedLineBackgroundSpan(ContextCompat.getColor(requireContext(), R.color.black_opaque), SUBTITLE_PADDING), 0, span.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
- span.setSpan(new OutlineSpan(), 0, span.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
binding.subtitlesText.setText(span);
binding.subtitlesText.setVisibility(View.VISIBLE);
diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/shared/OutlineSpan.kt b/app/src/main/java/org/jellyfin/androidtv/ui/shared/OutlineSpan.kt
deleted file mode 100644
index cf3eb4caf6..0000000000
--- a/app/src/main/java/org/jellyfin/androidtv/ui/shared/OutlineSpan.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.jellyfin.androidtv.ui.shared
-
-import android.graphics.Canvas
-import android.graphics.Color
-import android.graphics.Paint
-import android.text.style.ReplacementSpan
-
-/**
- * A class that draws the outlines of a text
- */
-class OutlineSpan : ReplacementSpan() {
- override fun getSize(
- paint: Paint,
- text: CharSequence,
- start: Int,
- end: Int,
- fm: Paint.FontMetricsInt?
- ): Int {
- if (fm != null) {
- fm.ascent = paint.fontMetricsInt.ascent
- fm.bottom = paint.fontMetricsInt.bottom
- fm.descent = paint.fontMetricsInt.descent
- fm.leading = paint.fontMetricsInt.leading
- fm.top = paint.fontMetricsInt.top
- }
-
- return paint.measureText(text, start, end).toInt()
- }
-
- override fun draw(
- canvas: Canvas,
- text: CharSequence,
- start: Int,
- end: Int,
- x: Float,
- top: Int,
- y: Int,
- bottom: Int,
- paint: Paint
- ) {
-
- val strokePaint = paint.apply {
- color = Color.BLACK
- style = Paint.Style.STROKE
- strokeWidth = 4f
- }
- canvas.drawText(text, start, end, x, y.toFloat(), strokePaint)
-
- val fillPaint = paint.apply {
- color = Color.WHITE
- style = Paint.Style.FILL
- }
- canvas.drawText(text, start, end, x, y.toFloat(), fillPaint)
- }
-}
diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/shared/StrokeTextView.kt b/app/src/main/java/org/jellyfin/androidtv/ui/shared/StrokeTextView.kt
new file mode 100644
index 0000000000..b0a4dcb3f3
--- /dev/null
+++ b/app/src/main/java/org/jellyfin/androidtv/ui/shared/StrokeTextView.kt
@@ -0,0 +1,46 @@
+package org.jellyfin.androidtv.ui.shared
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.content.ContextCompat
+import org.jellyfin.androidtv.R
+
+class StrokeTextView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+) : AppCompatTextView(context, attrs, defStyleAttr) {
+ var strokeWidth = 0.0f
+ private var isDrawing: Boolean = false
+
+ init {
+ val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.StrokeTextView)
+ strokeWidth = styledAttrs.getFloat(R.styleable.StrokeTextView_strokeWidth, 0.0f)
+ styledAttrs.recycle()
+ }
+
+ override fun invalidate() {
+ // To prevent infinite call of onDraw because setTextColor calls invalidate()
+ if (isDrawing) return
+ super.invalidate()
+ }
+
+ override fun onDraw(canvas: Canvas?) {
+ if (strokeWidth <= 0) return super.onDraw(canvas)
+ isDrawing = true
+ val initialColor = textColors
+
+ paint.style = Paint.Style.STROKE
+ paint.strokeWidth = strokeWidth
+ setTextColor(ContextCompat.getColor(context, R.color.black))
+ super.onDraw(canvas)
+
+ paint.style = Paint.Style.FILL
+ setTextColor(initialColor)
+ super.onDraw(canvas)
+ isDrawing = false
+ }
+}
diff --git a/app/src/main/res/layout/vlc_player_interface.xml b/app/src/main/res/layout/vlc_player_interface.xml
index 8cc478fe0e..2f3dd9f3d9 100644
--- a/app/src/main/res/layout/vlc_player_interface.xml
+++ b/app/src/main/res/layout/vlc_player_interface.xml
@@ -44,7 +44,7 @@
android:layout_height="match_parent"
android:layout_gravity="center" />
-
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index c2a80771c0..c7e5a0f84c 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -26,4 +26,7 @@
+
+
+