Fixed issue with </b> or </i> in export + changed max baseLinePadding

This commit is contained in:
Nikolaj Olsson 2016-08-09 18:54:52 +02:00
parent 3d6be5c7a5
commit b62b157b25
2 changed files with 114 additions and 16 deletions

View File

@ -801,6 +801,28 @@ namespace Nikse.SubtitleEdit.Core
return newTop; return newTop;
} }
public int CalcBottomCropping(Color transparentColor)
{
int y = Height - 1;
int cropping = 0;
while (y > 0)
{
int x = 0;
while (x < Width)
{
var c = GetPixel(x, y);
if (c != transparentColor && c.A != 0)
{
return cropping;
}
x++;
}
y--;
cropping++;
}
return cropping;
}
public void Fill(Color color) public void Fill(Color color)
{ {
var buffer = new byte[4]; var buffer = new byte[4];

View File

@ -1897,7 +1897,19 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
private static int CalcWidthViaDraw(string text, MakeBitmapParameter parameter) private static int CalcWidthViaDraw(string text, MakeBitmapParameter parameter)
{ {
//text = HtmlUtil.RemoveHtmlTags(text, true).Trim(); var nbmp = GenereateBitmapForCalc(text, parameter);
nbmp.CropTransparentSidesAndBottom(0, true);
return nbmp.Width;
}
private static int CalcButtomCropping(string text, MakeBitmapParameter parameter)
{
var nbmp = GenereateBitmapForCalc(text, parameter);
return nbmp.CalcBottomCropping(parameter.BorderColor);
}
private static NikseBitmap GenereateBitmapForCalc(string text, MakeBitmapParameter parameter)
{
text = text.Trim(); text = text.Trim();
var path = new GraphicsPath(); var path = new GraphicsPath();
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -1921,7 +1933,7 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
Font font = SetFont(parameter, parameter.SubtitleFontSize); Font font = SetFont(parameter, parameter.SubtitleFontSize);
Stack<Font> fontStack = new Stack<Font>(); var fontStack = new Stack<Font>();
while (i < text.Length) while (i < text.Length)
{ {
if (text.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) if (text.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase))
@ -2143,11 +2155,10 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
g.Dispose(); g.Dispose();
var nbmp = new NikseBitmap(bmp); var nbmp = new NikseBitmap(bmp);
nbmp.CropTransparentSidesAndBottom(0, true);
bmp.Dispose(); bmp.Dispose();
font.Dispose(); font.Dispose();
sf.Dispose(); sf.Dispose();
return nbmp.Width; return nbmp;
} }
internal static Bitmap GenerateImageFromTextWithStyle(MakeBitmapParameter parameter) internal static Bitmap GenerateImageFromTextWithStyle(MakeBitmapParameter parameter)
@ -2273,6 +2284,7 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
return bmp; return bmp;
} }
private static Dictionary<string, int> _paddingDictionary = new Dictionary<string, int>();
private static Bitmap GenerateImageFromTextWithStyleInner(MakeBitmapParameter parameter) private static Bitmap GenerateImageFromTextWithStyleInner(MakeBitmapParameter parameter)
{ {
string text = parameter.P.Text; string text = parameter.P.Text;
@ -2317,19 +2329,27 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
bmp = new Bitmap(sizeX, sizeY); bmp = new Bitmap(sizeX, sizeY);
} }
// align lines with gjpqy, a bit lower var paddingKey = font.Name + font.Size.ToString(CultureInfo.InvariantCulture);
int baseLinePadding;
if (_paddingDictionary.ContainsKey(paddingKey))
{
baseLinePadding = _paddingDictionary[paddingKey];
}
else
{
baseLinePadding = (int)Math.Round(TextDraw.MeasureTextHeight(font, "yjK)", parameter.SubtitleFontBold) - TextDraw.MeasureTextHeight(font, "ac", parameter.SubtitleFontBold));
baseLinePadding += 2;
_paddingDictionary.Add(paddingKey, baseLinePadding);
}
// align lines with "gjpqy,ýęçÇ/()[]" a bit lower
var lines = text.SplitToLines(); var lines = text.SplitToLines();
int baseLinePadding = 13;
if (parameter.SubtitleFontSize < 30)
baseLinePadding = 12;
if (parameter.SubtitleFontSize < 25)
baseLinePadding = 9;
if (lines.Length > 0) if (lines.Length > 0)
{ {
var lastLine = lines[lines.Length - 1]; var lastLine = lines[lines.Length - 1];
if (lastLine.Contains(new[] { 'g', 'j', 'p', 'q', 'y', ',', 'ý', 'ę', 'ç', 'Ç' })) if (lastLine.Contains(new[] { 'g', 'j', 'p', 'q', 'y', ',', 'ý', 'ę', 'ç', 'Ç', '/', '(', ')', '[', ']' }))
{ {
var textNoBelow = lastLine.Replace('g', 'a').Replace('j', 'a').Replace('p', 'a').Replace('q', 'a').Replace('y', 'a').Replace(',', 'a').Replace('ý', 'a').Replace('ę', 'a').Replace('ç', 'a').Replace('Ç', 'a'); var textNoBelow = lastLine.Replace('g', 'a').Replace('j', 'a').Replace('p', 'a').Replace('q', 'a').Replace('y', 'a').Replace(',', 'a').Replace('ý', 'a').Replace('ę', 'a').Replace('ç', 'a').Replace('Ç', 'a').Replace('/', 'a').Replace('(', 'a').Replace(')', 'a').Replace('[', 'a').Replace(']', 'a');
baseLinePadding -= (int)Math.Round((TextDraw.MeasureTextHeight(font, lastLine, parameter.SubtitleFontBold) - TextDraw.MeasureTextHeight(font, textNoBelow, parameter.SubtitleFontBold))); baseLinePadding -= (int)Math.Round((TextDraw.MeasureTextHeight(font, lastLine, parameter.SubtitleFontBold) - TextDraw.MeasureTextHeight(font, textNoBelow, parameter.SubtitleFontBold)));
} }
else else
@ -2706,8 +2726,36 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
sb.Append(' '); sb.Append(' ');
sb.Append(t); sb.Append(t);
} }
lastText.Append(sb);
TextDraw.DrawText(font, sf, path, sb, isItalic, isBold || parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); if (sb.Length > 0)
{
float addLeft = 0;
int oldPathPointIndex = path.PointCount - 1;
if (oldPathPointIndex < 0)
oldPathPointIndex = 0;
if (sb.Length > 0)
{
if (lastText.Length > 0 && left > 2)
left -= 1.5f;
lastText.Append(sb);
TextDraw.DrawText(font, sf, path, sb, isItalic, isBold || parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
}
if (path.PointCount > 0)
{
var list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
for (int k = oldPathPointIndex; k < list.Length; k++)
{
if (list[k].X > addLeft)
addLeft = list[k].X;
}
}
if (addLeft < 0.01)
addLeft = left + 2;
left = addLeft;
}
isItalic = false; isItalic = false;
i += 3; i += 3;
} }
@ -2730,8 +2778,36 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
sb.Append(' '); sb.Append(' ');
sb.Append(t); sb.Append(t);
} }
lastText.Append(sb);
TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint); if (sb.Length > 0)
{
float addLeft = 0;
int oldPathPointIndex = path.PointCount - 1;
if (oldPathPointIndex < 0)
oldPathPointIndex = 0;
if (sb.Length > 0)
{
if (lastText.Length > 0 && left > 2)
left -= 1.5f;
lastText.Append(sb);
TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
}
if (path.PointCount > 0)
{
var list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
for (int k = oldPathPointIndex; k < list.Length; k++)
{
if (list[k].X > addLeft)
addLeft = list[k].X;
}
}
if (addLeft < 0.01)
addLeft = left + 2;
left = addLeft;
}
isBold = false; isBold = false;
i += 3; i += 3;
} }