Break-line for placeholder titles when too long
This commit is contained in:
parent
23d8da9ae7
commit
757aab1943
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps text to fit within the specified width and height constraints.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to wrap.</param>
|
||||
/// <param name="paint">The paint to use for measuring.</param>
|
||||
/// <param name="maxWidth">Maximum width for each line.</param>
|
||||
/// <param name="maxHeight">Maximum total height.</param>
|
||||
/// <param name="fontSize">Font size (will be adjusted if needed).</param>
|
||||
/// <returns>List of text lines.</returns>
|
||||
private static System.Collections.Generic.List<string> 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<string>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user