diff --git a/Jellyfin.Plugin.SRFPlay/Utilities/PlaceholderImageGenerator.cs b/Jellyfin.Plugin.SRFPlay/Utilities/PlaceholderImageGenerator.cs
index 3d05157..1c82cb6 100644
--- a/Jellyfin.Plugin.SRFPlay/Utilities/PlaceholderImageGenerator.cs
+++ b/Jellyfin.Plugin.SRFPlay/Utilities/PlaceholderImageGenerator.cs
@@ -41,26 +41,25 @@ public static class PlaceholderImageGenerator
Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold)
};
- // Calculate font size to fit text (max 48, min 24)
+ // Calculate font size and wrap text if needed
float fontSize = 48;
textPaint.TextSize = fontSize;
- var textWidth = textPaint.MeasureText(text);
var maxWidth = Width * 0.85f;
+ var maxHeight = Height * 0.8f;
- if (textWidth > maxWidth)
+ var lines = WrapText(text, textPaint, maxWidth, maxHeight, ref fontSize);
+
+ // Draw each line centered
+ var lineHeight = fontSize * 1.2f;
+ var totalHeight = lines.Count * lineHeight;
+ var startY = ((Height - totalHeight) / 2) + fontSize;
+
+ foreach (var line in lines)
{
- fontSize = fontSize * maxWidth / textWidth;
- fontSize = fontSize < 24 ? 24 : fontSize;
- textPaint.TextSize = fontSize;
+ canvas.DrawText(line, Width / 2, startY, textPaint);
+ startY += lineHeight;
}
- // Center text vertically
- SKRect textBounds = default;
- textPaint.MeasureText(text, ref textBounds);
- var yPos = (Height / 2) - textBounds.MidY;
-
- canvas.DrawText(text, Width / 2, yPos, textPaint);
-
// Encode to PNG
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
@@ -70,4 +69,73 @@ public static class PlaceholderImageGenerator
stream.Position = 0;
return stream;
}
+
+ ///
+ /// Wraps text to fit within the specified width and height constraints.
+ ///
+ /// The text to wrap.
+ /// The paint to use for measuring.
+ /// Maximum width for each line.
+ /// Maximum total height.
+ /// Font size (will be adjusted if needed).
+ /// List of text lines.
+ private static System.Collections.Generic.List WrapText(
+ string text,
+ SKPaint paint,
+ float maxWidth,
+ float maxHeight,
+ ref float fontSize)
+ {
+ const float minFontSize = 20;
+ var words = text.Split(' ');
+ var lines = new System.Collections.Generic.List();
+
+ while (fontSize >= minFontSize)
+ {
+ paint.TextSize = fontSize;
+ lines.Clear();
+
+ var currentLine = string.Empty;
+ foreach (var word in words)
+ {
+ var testLine = string.IsNullOrEmpty(currentLine) ? word : $"{currentLine} {word}";
+ var testWidth = paint.MeasureText(testLine);
+
+ if (testWidth > maxWidth && !string.IsNullOrEmpty(currentLine))
+ {
+ lines.Add(currentLine);
+ currentLine = word;
+ }
+ else
+ {
+ currentLine = testLine;
+ }
+ }
+
+ if (!string.IsNullOrEmpty(currentLine))
+ {
+ lines.Add(currentLine);
+ }
+
+ // Check if total height fits
+ var lineHeight = fontSize * 1.2f;
+ var totalHeight = lines.Count * lineHeight;
+
+ if (totalHeight <= maxHeight)
+ {
+ break;
+ }
+
+ // Reduce font size and try again
+ fontSize -= 2;
+ }
+
+ // If still doesn't fit, just return what we have
+ if (lines.Count == 0)
+ {
+ lines.Add(text);
+ }
+
+ return lines;
+ }
}