Backport TextLabel optimizations

This commit is contained in:
spherallic 2023-04-25 16:45:52 +02:00
parent b54d7a48cc
commit 7e488497ef
1 changed files with 76 additions and 51 deletions

View File

@ -94,6 +94,11 @@ namespace CodeImp.DoomBuilder.Rendering
// Disposing // Disposing
private bool isdisposed; private bool isdisposed;
// ano - static stuff to prevent often alloc/dealloc performance hits
private static StringFormat strFormat;
private static SolidBrush brush;
private static Pen pen;
#endregion #endregion
#region ================== Properties #region ================== Properties
@ -156,7 +161,9 @@ namespace CodeImp.DoomBuilder.Rendering
this.texturesize = Size.Empty; //mxd this.texturesize = Size.Empty; //mxd
this.updateneeded = true; this.updateneeded = true;
this.textureupdateneeded = true; //mxd this.textureupdateneeded = true; //mxd
InitializeStatics();
// Register as resource // Register as resource
General.Map.Graphics.RegisterResource(this); General.Map.Graphics.RegisterResource(this);
@ -181,6 +188,8 @@ namespace CodeImp.DoomBuilder.Rendering
this.updateneeded = true; this.updateneeded = true;
this.textureupdateneeded = true; this.textureupdateneeded = true;
InitializeStatics();
// Register as resource // Register as resource
General.Map.Graphics.RegisterResource(this); General.Map.Graphics.RegisterResource(this);
@ -209,7 +218,28 @@ namespace CodeImp.DoomBuilder.Rendering
#endregion #endregion
#region ================== Methods #region ================== Methods
// ano - share resources instead of constantly alloc/dealloc
public void InitializeStatics()
{
if (strFormat == null)
{
strFormat = new StringFormat();
strFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.NoWrap;
strFormat.Alignment = StringAlignment.Center;
strFormat.LineAlignment = StringAlignment.Center;
}
if (brush == null)
{
// if we actually see magenta, know we made a mistake somewhere
brush = new SolidBrush(System.Drawing.Color.Magenta);
}
if (pen == null)
{
pen = new Pen(System.Drawing.Color.Magenta);
}
}
// This updates the text if needed // This updates the text if needed
public void Update(float translatex, float translatey, float scalex, float scaley) public void Update(float translatex, float translatey, float scalex, float scaley)
{ {
@ -347,73 +377,68 @@ namespace CodeImp.DoomBuilder.Rendering
private static Bitmap CreateLabelImage(string text, Font font, PixelColor color, PixelColor backcolor, bool drawbg, RectangleF textrect, RectangleF bgrect, Size texturesize, PointF textorigin) private static Bitmap CreateLabelImage(string text, Font font, PixelColor color, PixelColor backcolor, bool drawbg, RectangleF textrect, RectangleF bgrect, Size texturesize, PointF textorigin)
{ {
Bitmap result = new Bitmap(texturesize.Width, texturesize.Height); Bitmap result = new Bitmap(texturesize.Width, texturesize.Height);
using(Graphics g = Graphics.FromImage(result)) using (Graphics g = Graphics.FromImage(result))
{ {
g.SmoothingMode = SmoothingMode.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
g.CompositingQuality = CompositingQuality.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality;
// Draw text // Draw text with BG
using(StringFormat sf = new StringFormat()) if (drawbg)
{ {
sf.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.NoWrap; GraphicsPath p = new GraphicsPath();
sf.Alignment = StringAlignment.Center; float radius = textorigin.X;
sf.LineAlignment = StringAlignment.Center; const float outlinewidth = 1;
// Draw text with BG RectangleF pathrect = bgrect;
if(drawbg) pathrect.Width -= 1;
{ pathrect.Height -= 1;
GraphicsPath p = new GraphicsPath();
float radius = textorigin.X;
const float outlinewidth = 1;
RectangleF pathrect = bgrect; // Left line
pathrect.Width -= 1; p.AddLine(pathrect.Left, pathrect.Bottom - radius + outlinewidth, pathrect.Left, pathrect.Top + radius);
pathrect.Height -= 1; p.AddArc(pathrect.Left, pathrect.Top, radius, radius, 180, 90);
// Left line // Top line
p.AddLine(pathrect.Left, pathrect.Bottom - radius + outlinewidth, pathrect.Left, pathrect.Top + radius); p.AddLine(pathrect.Left + radius, pathrect.Top, pathrect.Right - radius, pathrect.Top);
p.AddArc(pathrect.Left, pathrect.Top, radius, radius, 180, 90); p.AddArc(pathrect.Right - radius, pathrect.Top, radius, radius, 270, 90);
// Top line // Right line
p.AddLine(pathrect.Left + radius, pathrect.Top, pathrect.Right - radius, pathrect.Top); p.AddLine(pathrect.Right, pathrect.Top + radius, pathrect.Right, pathrect.Bottom - radius);
p.AddArc(pathrect.Right - radius, pathrect.Top, radius, radius, 270, 90); p.AddArc(pathrect.Right - radius, pathrect.Bottom - radius, radius, radius, 0, 90);
// Right line // Bottom line
p.AddLine(pathrect.Right, pathrect.Top + radius, pathrect.Right, pathrect.Bottom - radius); p.AddLine(pathrect.Left + radius, pathrect.Bottom, pathrect.Left + radius, pathrect.Bottom);
p.AddArc(pathrect.Right - radius, pathrect.Bottom - radius, radius, radius, 0, 90); p.AddArc(pathrect.Left, pathrect.Bottom - radius, radius, radius, 90, 90);
// Bottom line // Fill'n'draw bg
p.AddLine(pathrect.Left + radius, pathrect.Bottom, pathrect.Left + radius, pathrect.Bottom); brush.Color = color.ToColor();
p.AddArc(pathrect.Left, pathrect.Bottom - radius, radius, radius, 90, 90);
// Fill'n'draw bg g.FillPath(brush, p);
using(SolidBrush brush = new SolidBrush(color.ToColor()))
g.FillPath(brush, p);
using(Pen pen = new Pen(backcolor.ToColor(), outlinewidth)) pen.Color = backcolor.ToColor();
g.DrawPath(pen, p);
// Draw text g.DrawPath(pen, p);
textrect.Inflate(4, 2);
using(SolidBrush brush = new SolidBrush(backcolor.ToColor()))
g.DrawString(text, font, brush, textrect, sf);
}
// Draw plain text
else
{
RectangleF plainbgrect = textrect;
if(text.Length > 1) plainbgrect.Inflate(6, 2);
RectangleF plaintextrect = textrect; // Draw text
plaintextrect.Inflate(6, 4); textrect.Inflate(4, 2);
brush.Color = backcolor.ToColor();
using(SolidBrush brush = new SolidBrush(backcolor.ToColor())) g.DrawString(text, font, brush, textrect, strFormat);
g.FillRectangle(brush, plainbgrect); }
// Draw plain text
else
{
RectangleF plainbgrect = textrect;
if (text.Length > 1) plainbgrect.Inflate(6, 2);
using(SolidBrush brush = new SolidBrush(color.ToColor())) RectangleF plaintextrect = textrect;
g.DrawString(text, font, brush, plaintextrect, sf); plaintextrect.Inflate(6, 4);
}
brush.Color = backcolor.ToColor();
g.FillRectangle(brush, plainbgrect);
brush.Color = color.ToColor();
g.DrawString(text, font, brush, plaintextrect, strFormat);
} }
} }