diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 6ed4ac3..15f4f41 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -1368,9 +1368,7 @@ Designer ThingsFiltersForm.cs - - UpdateForm.cs diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index 640fda1..ae36337 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -2533,12 +2533,6 @@ namespace CodeImp.DoomBuilder return io.GetType() == t; } - //mxd - public SizeF GetTextSize(string text, float scale) - { - return graphics.Font.GetTextSize(text, scale); - } - //mxd [BeginAction("snapvertstogrid")] private void SnapSelectedMapElementsToGrid() diff --git a/Source/Core/Rendering/D3DDevice.cs b/Source/Core/Rendering/D3DDevice.cs index 888dfb1..3ad542f 100644 --- a/Source/Core/Rendering/D3DDevice.cs +++ b/Source/Core/Rendering/D3DDevice.cs @@ -57,8 +57,6 @@ namespace CodeImp.DoomBuilder.Rendering private ShaderManager shaders; private Surface backbuffer; private Surface depthbuffer; - private TextFont font; - private ResourceImage fonttexture; // Disposing private bool isdisposed; @@ -75,8 +73,6 @@ namespace CodeImp.DoomBuilder.Rendering internal ShaderManager Shaders { get { return shaders; } } internal Surface BackBuffer { get { return backbuffer; } } internal Surface DepthBuffer { get { return depthbuffer; } } - internal TextFont Font { get { return font; } } - internal Texture FontTexture { get { return fonttexture.Texture; } } internal Filter PostFilter { get { return postfilter; } } internal Filter MipGenerateFilter { get { return mipgeneratefilter; } } @@ -100,18 +96,16 @@ namespace CodeImp.DoomBuilder.Rendering // Disposer public void Dispose() { - // Not already disposed? - if (!isdisposed) - { - // Clean up - foreach (ID3DResource res in resources) res.UnloadResource(); - if (shaders != null) shaders.Dispose(); - rendertarget = null; - if (backbuffer != null) backbuffer.Dispose(); - if (depthbuffer != null) depthbuffer.Dispose(); - if (font != null) font.Dispose(); - if (fonttexture != null) fonttexture.Dispose(); - if (device != null) device.Dispose(); + // Not already disposed? + if(!isdisposed) + { + // Clean up + foreach(ID3DResource res in resources) res.UnloadResource(); + if(shaders != null) shaders.Dispose(); + rendertarget = null; + if(backbuffer != null) backbuffer.Dispose(); + if(depthbuffer != null) depthbuffer.Dispose(); + if(device != null) device.Dispose(); if (ObjectTable.Objects.Count > 1) //mxd. Direct3D itself is not disposed while the editor is running { @@ -290,14 +284,6 @@ namespace CodeImp.DoomBuilder.Rendering // Create shader manager shaders = new ShaderManager(this); - // Font - postfilter = Filter.Box; // Only for the font. This will be reset in SetupSettings (see below) - font = new TextFont(); - fonttexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Font.png"); - fonttexture.LoadImage(); - fonttexture.MipMapLevels = 2; - fonttexture.CreateTexture(); - // Initialize settings SetupSettings(); diff --git a/Source/Core/Rendering/IRenderer2D.cs b/Source/Core/Rendering/IRenderer2D.cs index 6ae6863..ed14180 100644 --- a/Source/Core/Rendering/IRenderer2D.cs +++ b/Source/Core/Rendering/IRenderer2D.cs @@ -76,6 +76,7 @@ namespace CodeImp.DoomBuilder.Rendering void RenderArrows(ICollection line); //mxd void RenderArrows(ICollection line, bool transformcoords); //mxd void RenderText(TextLabel text); + void RenderText(List labels); //mxd void RenderGeometry(FlatVertex[] vertices, ImageData texture, bool transformcoords); void RenderHighlight(FlatVertex[] vertices, int color); //mxd void RedrawSurface(); diff --git a/Source/Core/Rendering/PixelColor.cs b/Source/Core/Rendering/PixelColor.cs index a94b303..aee5061 100644 --- a/Source/Core/Rendering/PixelColor.cs +++ b/Source/Core/Rendering/PixelColor.cs @@ -208,6 +208,12 @@ namespace CodeImp.DoomBuilder.Rendering { return "[A=" + a + ", R=" + r + ", G=" + g + ", B=" + b + "]"; } + + //mxd + public bool Equals(PixelColor other) + { + return (r == other.r && g == other.g && b == other.b && a == other.a); + } #endregion } diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index e5e5ad8..ceeb3bf 100644 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -1678,34 +1678,90 @@ namespace CodeImp.DoomBuilder.Rendering } // This renders text - public void RenderText(TextLabel text) + public void RenderText(TextLabel label) { - // Update the text if needed - text.Update(translatex, translatey, scale, -scale); - - // Text is created? - if(text.VertexBuffer != null) - { - // Set renderstates for rendering - graphics.Device.SetRenderState(RenderState.CullMode, Cull.None); - graphics.Device.SetRenderState(RenderState.ZEnable, false); - graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true); - graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false); - graphics.Device.SetRenderState(RenderState.TextureFactor, -1); - graphics.Device.SetRenderState(RenderState.FogEnable, false); - graphics.Shaders.Display2D.Texture1 = graphics.FontTexture; - SetWorldTransformation(false); - graphics.Shaders.Display2D.SetSettings(1f, 1f, 0f, 1f, true); - graphics.Device.SetStreamSource(0, text.VertexBuffer, 0, FlatVertex.Stride); + //mxd. Update the text if needed + RectangleF bbox = label.Update(translatex, translatey, scale, -scale); - // Draw - graphics.Shaders.Display2D.Begin(); - graphics.Shaders.Display2D.BeginPass(1); //mxd - //graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, text.NumFaces >> 1); //mxd. Seems to be working fine without this line, soooo... - graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, text.NumFaces); - graphics.Shaders.Display2D.EndPass(); - graphics.Shaders.Display2D.End(); + //mxd. Have graphics / on screen? + if(label.VertexBuffer == null || (bbox.Right < 0.1f) || (bbox.Left > windowsize.Width) || (bbox.Bottom < 0.1f) || (bbox.Top > windowsize.Height)) + return; + + // Set renderstates for rendering + graphics.Device.SetRenderState(RenderState.CullMode, Cull.None); + graphics.Device.SetRenderState(RenderState.ZEnable, false); + graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true); + graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false); + graphics.Device.SetRenderState(RenderState.TextureFactor, -1); + graphics.Device.SetRenderState(RenderState.FogEnable, false); + graphics.Shaders.Display2D.Texture1 = label.Texture; + SetWorldTransformation(false); + graphics.Shaders.Display2D.SetSettings(1f, 1f, 0f, 1f, true); + graphics.Device.SetStreamSource(0, label.VertexBuffer, 0, FlatVertex.Stride); + + // Draw + graphics.Shaders.Display2D.Begin(); + graphics.Shaders.Display2D.BeginPass(1); //mxd + graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); + graphics.Shaders.Display2D.EndPass(); + graphics.Shaders.Display2D.End(); + } + + //mxd. This renders text + public void RenderText(List labels) + { + // Update labels + int skipped = 0; + foreach(TextLabel label in labels) + { + // Update the text if needed + RectangleF bbox = label.Update(translatex, translatey, scale, -scale); + + // Have graphics / on screen? + if(label.VertexBuffer == null || (bbox.Right < 0.1f) || (bbox.Left > windowsize.Width) || (bbox.Bottom < 0.1f) || (bbox.Top > windowsize.Height)) + { + label.SkipRendering = true; + skipped++; + } + else + { + label.SkipRendering = false; + } } + + if(labels.Count == skipped) return; + + // Set renderstates for rendering + graphics.Device.SetRenderState(RenderState.CullMode, Cull.None); + graphics.Device.SetRenderState(RenderState.ZEnable, false); + graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, true); + graphics.Device.SetRenderState(RenderState.AlphaTestEnable, false); + graphics.Device.SetRenderState(RenderState.TextureFactor, -1); + graphics.Device.SetRenderState(RenderState.FogEnable, false); + SetWorldTransformation(false); + graphics.Shaders.Display2D.SetSettings(1f, 1f, 0f, 1f, true); + + // Begin drawing + graphics.Shaders.Display2D.Begin(); + graphics.Shaders.Display2D.BeginPass(1); + + foreach(TextLabel label in labels) + { + // Text is created? + if(!label.SkipRendering) + { + graphics.Shaders.Display2D.Texture1 = label.Texture; + graphics.Shaders.Display2D.ApplySettings(); + graphics.Device.SetStreamSource(0, label.VertexBuffer, 0, FlatVertex.Stride); + + // Draw + graphics.Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); + } + } + + // Finish drawing + graphics.Shaders.Display2D.EndPass(); + graphics.Shaders.Display2D.End(); } // This renders a rectangle with given border size and color diff --git a/Source/Core/Rendering/TextFont.cs b/Source/Core/Rendering/TextFont.cs index feb0451..a9da6de 100644 --- a/Source/Core/Rendering/TextFont.cs +++ b/Source/Core/Rendering/TextFont.cs @@ -13,7 +13,7 @@ */ #endregion - +/* #region ================== Namespaces using System; @@ -245,3 +245,4 @@ namespace CodeImp.DoomBuilder.Rendering #endregion } } +*/ \ No newline at end of file diff --git a/Source/Core/Rendering/TextLabel.cs b/Source/Core/Rendering/TextLabel.cs index f53eaaf..12a8a93 100644 --- a/Source/Core/Rendering/TextLabel.cs +++ b/Source/Core/Rendering/TextLabel.cs @@ -17,11 +17,15 @@ #region ================== Namespaces using System; -using System.Text; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Text; +using System.IO; using System.Drawing; using SlimDX.Direct3D9; using SlimDX; using CodeImp.DoomBuilder.Geometry; +using Font = System.Drawing.Font; #endregion @@ -37,22 +41,24 @@ namespace CodeImp.DoomBuilder.Rendering // The text is stored as a polygon in a vertex buffer private VertexBuffer textbuffer; - private int numfaces; - private int capacity; + private Texture texture; + private Font font; //mxd // Text settings private string text; private RectangleF rect; + private RectangleF absview; //mxd private bool transformcoords; private PixelColor color; private PixelColor backcolor; - private float scale; private TextAlignmentX alignx; private TextAlignmentY aligny; - private SizeF size; + private SizeF textsize; + private bool drawbg; //mxd // This keeps track if changes were made private bool updateneeded; + private bool textureupdateneeded; //mxd private float lasttranslatex = float.MinValue; private float lasttranslatey; private float lastscalex; @@ -73,16 +79,18 @@ namespace CodeImp.DoomBuilder.Rendering public float Height { get { return rect.Height; } set { rect.Height = value; updateneeded = true; } } public float Right { get { return rect.Right; } set { rect.Width = value - rect.X + 1f; updateneeded = true; } } public float Bottom { get { return rect.Bottom; } set { rect.Height = value - rect.Y + 1f; updateneeded = true; } } - public string Text { get { return text; } set { if(text != value.ToUpperInvariant()) { text = value.ToUpperInvariant(); updateneeded = true; } } } + public string Text { get { return text; } set { if(text != value) { text = value; textureupdateneeded = true; } } } + public Font Font { get { return font; } set { font = value; textureupdateneeded = true; } } //mxd public bool TransformCoords { get { return transformcoords; } set { transformcoords = value; updateneeded = true; } } - public SizeF TextSize { get { return size; } } - public float Scale { get { return scale; } set { scale = value; updateneeded = true; } } + public SizeF TextSize { get { return textsize; } } public TextAlignmentX AlignX { get { return alignx; } set { alignx = value; updateneeded = true; } } public TextAlignmentY AlignY { get { return aligny; } set { aligny = value; updateneeded = true; } } - public PixelColor Color { get { return color; } set { color = value; updateneeded = true; } } - public PixelColor Backcolor { get { return backcolor; } set { backcolor = value; updateneeded = true; } } + public PixelColor Color { get { return color; } set { if(!color.Equals(value)) { color = value; textureupdateneeded = true; } } } + public PixelColor Backcolor { get { return backcolor; } set { if(!backcolor.Equals(value)) { backcolor = value; textureupdateneeded = true; } } } + public bool DrawBackground { get { return drawbg; } set { if(drawbg != value) { drawbg = value; textureupdateneeded = true; } } } //mxd + internal Texture Texture { get { return texture; } } //mxd internal VertexBuffer VertexBuffer { get { return textbuffer; } } - internal int NumFaces { get { return numfaces; } } + internal bool SkipRendering; //mxd // Disposing public bool IsDisposed { get { return isdisposed; } } @@ -92,20 +100,19 @@ namespace CodeImp.DoomBuilder.Rendering #region ================== Constructor / Disposer // Constructor - public TextLabel(int capacity) + public TextLabel() { // Initialize this.text = ""; + this.font = new Font(General.MainWindow.Font.FontFamily, (float)Math.Round(General.MainWindow.Font.SizeInPoints * 1.25f), FontStyle.Regular); //mxd this.rect = new RectangleF(0f, 0f, 1f, 1f); this.color = new PixelColor(255, 255, 255, 255); - this.backcolor = new PixelColor(0, 0, 0, 0); - this.scale = 10f; + this.backcolor = new PixelColor(255, 0, 0, 0); this.alignx = TextAlignmentX.Center; this.aligny = TextAlignmentY.Top; - this.size = new SizeF(0f, 0f); + this.textsize = new SizeF(); this.updateneeded = true; - this.numfaces = 0; - this.capacity = capacity; + this.textureupdateneeded = true; //mxd // Register as resource General.Map.Graphics.RegisterResource(this); @@ -136,46 +143,50 @@ namespace CodeImp.DoomBuilder.Rendering #region ================== Methods // This updates the text if needed - internal void Update(float translatex, float translatey, float scalex, float scaley) + internal RectangleF Update(float translatex, float translatey, float scalex, float scaley) { // Check if transformation changed and needs to be updated - if(transformcoords) + if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey || + scalex != lastscalex || scaley != lastscaley)) { - if(translatex != lasttranslatex || translatey != lasttranslatey || - scalex != lastscalex || scaley != lastscaley) + lasttranslatex = translatex; //mxd + lasttranslatey = translatey; //mxd + lastscalex = scalex; //mxd + lastscaley = scaley; //mxd + updateneeded = true; + } + + //mxd. Update texture if needed + if(textureupdateneeded) + { + // Get rid of old texture + if(texture != null) { - lasttranslatex = translatex; //mxd - lasttranslatey = translatey; //mxd - lastscalex = scalex; //mxd - lastscaley = scaley; //mxd - updateneeded = true; + texture.Dispose(); + texture = null; } + + // Create label image + Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg); + textsize = img.Size; + + // Create texture + MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096); + img.Save(memstream, ImageFormat.Bmp); + memstream.Seek(0, SeekOrigin.Begin); + + texture = Texture.FromStream(General.Map.Graphics.Device, memstream, (int)memstream.Length, + img.Size.Width, img.Size.Height, 1, Usage.None, Format.Unknown, + Pool.Managed, General.Map.Graphics.PostFilter, General.Map.Graphics.MipGenerateFilter, 0); } // Update if needed - if(updateneeded) + if(updateneeded || textureupdateneeded) { // Only build when there are any vertices if(text.Length > 0) { - // Do we have to make a new buffer? - if((textbuffer == null) || (text.Length > capacity)) - { - // Dispose previous - if(textbuffer != null) textbuffer.Dispose(); - - // Determine new capacity - if(capacity < text.Length) capacity = text.Length; - - // Create the buffer - textbuffer = new VertexBuffer(General.Map.Graphics.Device, - capacity * 12 * FlatVertex.Stride, - Usage.Dynamic | Usage.WriteOnly, - VertexFormat.None, Pool.Default); - } - // Transform? - RectangleF absview; if(transformcoords) { // Calculate absolute coordinates @@ -183,24 +194,21 @@ namespace CodeImp.DoomBuilder.Rendering Vector2D rb = new Vector2D(rect.Right, rect.Bottom); lt = lt.GetTransformed(translatex, translatey, scalex, scaley); rb = rb.GetTransformed(translatex, translatey, scalex, scaley); - absview = new RectangleF(lt.x, lt.y, rb.x - lt.x, rb.y - lt.y); + absview = new RectangleF((float)Math.Round(lt.x), (float)Math.Round(lt.y), rb.x - lt.x, rb.y - lt.y); } else { // Fixed coordinates absview = rect; } - - // Calculate text dimensions - size = General.Map.Graphics.Font.GetTextSize(text, scale); // Align the text horizontally float beginx = 0; switch(alignx) { case TextAlignmentX.Left: beginx = absview.X; break; - case TextAlignmentX.Center: beginx = absview.X + (absview.Width - size.Width) * 0.5f; break; - case TextAlignmentX.Right: beginx = absview.X + absview.Width - size.Width; break; + case TextAlignmentX.Center: beginx = absview.X + (absview.Width - textsize.Width) * 0.5f; break; + case TextAlignmentX.Right: beginx = absview.X + absview.Width - textsize.Width; break; } // Align the text vertically @@ -208,63 +216,149 @@ namespace CodeImp.DoomBuilder.Rendering switch(aligny) { case TextAlignmentY.Top: beginy = absview.Y; break; - case TextAlignmentY.Middle: beginy = absview.Y + (absview.Height - size.Height) * 0.5f; break; - case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - size.Height; break; + case TextAlignmentY.Middle: beginy = absview.Y + (absview.Height - textsize.Height) * 0.5f; break; + case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - textsize.Height; break; } - // Get the ASCII bytes for the text - byte[] textbytes = Encoding.ASCII.GetBytes(text); + // Do we have to make a new buffer? + if(textbuffer == null) + { + // Create the buffer + textbuffer = new VertexBuffer(General.Map.Graphics.Device, 4 * FlatVertex.Stride, + Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default); + } - // Lock the buffer - DataStream stream = textbuffer.Lock(0, capacity * 12 * FlatVertex.Stride, - LockFlags.Discard | LockFlags.NoSystemLock); - - // Go for all chars in text to create the backgrounds - float textx = beginx; - foreach(byte b in textbytes) - General.Map.Graphics.Font.SetupVertices(stream, b, scale, backcolor.ToInt(), - ref textx, beginy, size.Height, 0.5f); - - // Go for all chars in text to create the text - textx = beginx; - foreach(byte b in textbytes) - General.Map.Graphics.Font.SetupVertices(stream, b, scale, color.ToInt(), - ref textx, beginy, size.Height, 0.0f); + //mxd. Lock the buffer + using(DataStream stream = textbuffer.Lock(0, 4 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock)) + { + FlatQuad quad = new FlatQuad(PrimitiveType.TriangleStrip, beginx, beginy, beginx + textsize.Width, beginy + textsize.Height); + stream.WriteRange(quad.Vertices); + } // Done filling the vertex buffer textbuffer.Unlock(); - stream.Dispose(); - - // Calculate number of triangles - numfaces = text.Length * 4; } else { // No faces in polygon - numfaces = 0; - size = new SizeF(0f, 0f); + if(textbuffer != null) textbuffer.Dispose(); //mxd + textsize = new SizeF(); } // Text updated updateneeded = false; + textureupdateneeded = false; //mxd } + + return absview; //mxd + } + + //mxd + private static Bitmap CreateLabelImage(string text, Font font, PixelColor color, PixelColor backcolor, bool drawbg) + { + PointF textorigin = new PointF(4, 3); + RectangleF textrect = new RectangleF(textorigin, General.Interface.MeasureString(text, font)); + textrect.Width = (float)Math.Round(textrect.Width); + textrect.Height = (float)Math.Round(textrect.Height); + RectangleF bgrect = new RectangleF(0, 0, textrect.Width + textorigin.X * 2, textrect.Height + textorigin.Y * 2); + + Bitmap result = new Bitmap((int)bgrect.Width, (int)bgrect.Height); + using(Graphics g = Graphics.FromImage(result)) + { + g.SmoothingMode = SmoothingMode.HighQuality; + g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; + g.CompositingQuality = CompositingQuality.HighQuality; + + // Draw text + using(StringFormat sf = new StringFormat()) + { + sf.FormatFlags = StringFormatFlags.NoWrap; + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + + // Draw text with BG + if(drawbg) + { + GraphicsPath p = new GraphicsPath(); + float radius = textorigin.X; + const float outlinewidth = 1; + + RectangleF pathrect = bgrect; + pathrect.Width -= 1; + pathrect.Height -= 1; + + // Left line + p.AddLine(pathrect.Left, pathrect.Bottom - radius + outlinewidth, pathrect.Left, pathrect.Top + radius); + p.AddArc(pathrect.Left, pathrect.Top, radius, radius, 180, 90); + + // Top line + p.AddLine(pathrect.Left + radius, pathrect.Top, pathrect.Right - radius, pathrect.Top); + p.AddArc(pathrect.Right - radius, pathrect.Top, radius, radius, 270, 90); + + // Right line + p.AddLine(pathrect.Right, pathrect.Top + radius, pathrect.Right, pathrect.Bottom - radius); + p.AddArc(pathrect.Right - radius, pathrect.Bottom - radius, radius, radius, 0, 90); + + // Bottom line + p.AddLine(pathrect.Left + radius, pathrect.Bottom, pathrect.Left + radius, pathrect.Bottom); + p.AddArc(pathrect.Left, pathrect.Bottom - radius, radius, radius, 90, 90); + + // Fill'n'draw bg + using(SolidBrush brush = new SolidBrush(color.ToColor())) + g.FillPath(brush, p); + + using(Pen pen = new Pen(backcolor.ToColor(), outlinewidth)) + g.DrawPath(pen, p); + + // Draw text + using(SolidBrush brush = new SolidBrush(backcolor.ToColor())) + g.DrawString(text, font, brush, textrect, sf); + } + // Draw text with outline + else + { + RectangleF pathrect = textrect; + pathrect.Inflate(1, 3); + + GraphicsPath p = new GraphicsPath(); + p.AddString(text, font.FontFamily, (int)font.Style, g.DpiY * font.Size / 72f, pathrect, sf); + + // Draw'n'fill text + using(Pen pen = new Pen(backcolor.ToColor(), 3)) + g.DrawPath(pen, p); + + using(SolidBrush brush = new SolidBrush(color.ToColor())) + g.FillPath(brush, p); + } + } + } + + return result; } // This unloads the resources public void UnloadResource() { // Clean up - if(textbuffer != null) textbuffer.Dispose(); - textbuffer = null; + if(textbuffer != null) + { + textbuffer.Dispose(); + textbuffer = null; + } + + if(texture != null) //mxd + { + texture.Dispose(); + texture = null; + } // Need to update before we can render updateneeded = true; + textureupdateneeded = true; //mxd } // This (re)loads the resources - public void ReloadResource() - { - } + public void ReloadResource() { } #endregion } diff --git a/Source/Core/Resources/Font.cfg b/Source/Core/Resources/Font.cfg deleted file mode 100644 index 8a0f9fd..0000000 --- a/Source/Core/Resources/Font.cfg +++ /dev/null @@ -1,710 +0,0 @@ -count = 64; - -chars -{ - - 65 - { - width = 26; - height = 42; - u1 = 0.011719f; - v1 = -0.003906f; - u2 = 0.078125f; - v2 = 0.195313f; - } - - - 66 - { - width = 26; - height = 42; - u1 = 0.082031f; - v1 = -0.003906f; - u2 = 0.148438f; - v2 = 0.195313f; - } - - - 67 - { - width = 26; - height = 42; - u1 = 0.152344f; - v1 = -0.003906f; - u2 = 0.21875f; - v2 = 0.195313f; - } - - - 68 - { - width = 26; - height = 42; - u1 = 0.222656f; - v1 = -0.003906f; - u2 = 0.289063f; - v2 = 0.195313f; - } - - - 69 - { - width = 24; - height = 42; - u1 = 0.292969f; - v1 = -0.003906f; - u2 = 0.355469f; - v2 = 0.195313f; - } - - - 70 - { - width = 22; - height = 42; - u1 = 0.359375f; - v1 = -0.003906f; - u2 = 0.417969f; - v2 = 0.195313f; - } - - - 71 - { - width = 28; - height = 42; - u1 = 0.421875f; - v1 = -0.003906f; - u2 = 0.492188f; - v2 = 0.195313f; - } - - - 72 - { - width = 28; - height = 42; - u1 = 0.496094f; - v1 = -0.003906f; - u2 = 0.566406f; - v2 = 0.195313f; - } - - - 73 - { - width = 13; - height = 42; - u1 = 0.570313f; - v1 = -0.003906f; - u2 = 0.611328f; - v2 = 0.195313f; - } - - - 74 - { - width = 22; - height = 42; - u1 = 0.615234f; - v1 = -0.003906f; - u2 = 0.673828f; - v2 = 0.195313f; - } - - - 75 - { - width = 28; - height = 42; - u1 = 0.677734f; - v1 = -0.003906f; - u2 = 0.748047f; - v2 = 0.195313f; - } - - - 76 - { - width = 22; - height = 42; - u1 = 0.751953f; - v1 = -0.003906f; - u2 = 0.810547f; - v2 = 0.195313f; - } - - - 77 - { - width = 31; - height = 42; - u1 = 0.814453f; - v1 = -0.003906f; - u2 = 0.890625f; - v2 = 0.195313f; - } - - - 78 - { - width = 28; - height = 42; - u1 = 0.894531f; - v1 = -0.003906f; - u2 = 0.964844f; - v2 = 0.195313f; - } - - - 79 - { - width = 28; - height = 42; - u1 = 0.011719f; - v1 = 0.183594f; - u2 = 0.082031f; - v2 = 0.382813f; - } - - - 80 - { - width = 24; - height = 42; - u1 = 0.085938f; - v1 = 0.183594f; - u2 = 0.148438f; - v2 = 0.382813f; - } - - - 81 - { - width = 28; - height = 42; - u1 = 0.152344f; - v1 = 0.183594f; - u2 = 0.222656f; - v2 = 0.382813f; - } - - - 82 - { - width = 26; - height = 42; - u1 = 0.226563f; - v1 = 0.183594f; - u2 = 0.292969f; - v2 = 0.382813f; - } - - - 83 - { - width = 24; - height = 42; - u1 = 0.296875f; - v1 = 0.183594f; - u2 = 0.359375f; - v2 = 0.382813f; - } - - - 84 - { - width = 24; - height = 42; - u1 = 0.363281f; - v1 = 0.183594f; - u2 = 0.425781f; - v2 = 0.382813f; - } - - - 85 - { - width = 28; - height = 42; - u1 = 0.429688f; - v1 = 0.183594f; - u2 = 0.5f; - v2 = 0.382813f; - } - - - 86 - { - width = 26; - height = 42; - u1 = 0.503906f; - v1 = 0.183594f; - u2 = 0.570313f; - v2 = 0.382813f; - } - - - 87 - { - width = 33; - height = 42; - u1 = 0.574219f; - v1 = 0.183594f; - u2 = 0.654297f; - v2 = 0.382813f; - } - - - 88 - { - width = 26; - height = 42; - u1 = 0.658203f; - v1 = 0.183594f; - u2 = 0.724609f; - v2 = 0.382813f; - } - - - 89 - { - width = 26; - height = 42; - u1 = 0.728516f; - v1 = 0.183594f; - u2 = 0.794922f; - v2 = 0.382813f; - } - - - 90 - { - width = 24; - height = 42; - u1 = 0.798828f; - v1 = 0.183594f; - u2 = 0.861328f; - v2 = 0.382813f; - } - - - 48 - { - width = 22; - height = 42; - u1 = 0.865234f; - v1 = 0.183594f; - u2 = 0.923828f; - v2 = 0.382813f; - } - - - 49 - { - width = 22; - height = 42; - u1 = 0.927734f; - v1 = 0.183594f; - u2 = 0.986328f; - v2 = 0.382813f; - } - - - 50 - { - width = 22; - height = 42; - u1 = 0.011719f; - v1 = 0.371094f; - u2 = 0.070313f; - v2 = 0.570313f; - } - - - 51 - { - width = 22; - height = 42; - u1 = 0.074219f; - v1 = 0.371094f; - u2 = 0.132813f; - v2 = 0.570313f; - } - - - 52 - { - width = 22; - height = 42; - u1 = 0.136719f; - v1 = 0.371094f; - u2 = 0.195313f; - v2 = 0.570313f; - } - - - 53 - { - width = 22; - height = 42; - u1 = 0.199219f; - v1 = 0.371094f; - u2 = 0.257813f; - v2 = 0.570313f; - } - - - 54 - { - width = 22; - height = 42; - u1 = 0.261719f; - v1 = 0.371094f; - u2 = 0.320313f; - v2 = 0.570313f; - } - - - 55 - { - width = 22; - height = 42; - u1 = 0.324219f; - v1 = 0.371094f; - u2 = 0.382813f; - v2 = 0.570313f; - } - - - 56 - { - width = 22; - height = 42; - u1 = 0.386719f; - v1 = 0.371094f; - u2 = 0.445313f; - v2 = 0.570313f; - } - - - 57 - { - width = 22; - height = 42; - u1 = 0.449219f; - v1 = 0.371094f; - u2 = 0.507813f; - v2 = 0.570313f; - } - - - 32 - { - width = 12; - height = 42; - u1 = 0.511719f; - v1 = 0.371094f; - u2 = 0.550781f; - v2 = 0.570313f; - } - - - 33 - { - width = 12; - height = 42; - u1 = 0.554688f; - v1 = 0.371094f; - u2 = 0.59375f; - v2 = 0.570313f; - } - - - 64 - { - width = 25; - height = 42; - u1 = 0.597656f; - v1 = 0.371094f; - u2 = 0.662109f; - v2 = 0.570313f; - } - - - 35 - { - width = 22; - height = 42; - u1 = 0.666016f; - v1 = 0.371094f; - u2 = 0.724609f; - v2 = 0.570313f; - } - - - 36 - { - width = 22; - height = 42; - u1 = 0.728516f; - v1 = 0.371094f; - u2 = 0.787109f; - v2 = 0.570313f; - } - - - 37 - { - width = 33; - height = 42; - u1 = 0.791016f; - v1 = 0.371094f; - u2 = 0.871094f; - v2 = 0.570313f; - } - - - 94 - { - width = 22; - height = 42; - u1 = 0.875f; - v1 = 0.371094f; - u2 = 0.933594f; - v2 = 0.570313f; - } - - - 38 - { - width = 29; - height = 42; - u1 = 0.011719f; - v1 = 0.558594f; - u2 = 0.083984f; - v2 = 0.757813f; - } - - - 42 - { - width = 19; - height = 42; - u1 = 0.087891f; - v1 = 0.558594f; - u2 = 0.140625f; - v2 = 0.757813f; - } - - - 40 - { - width = 13; - height = 42; - u1 = 0.144531f; - v1 = 0.558594f; - u2 = 0.185547f; - v2 = 0.757813f; - } - - - 41 - { - width = 13; - height = 42; - u1 = 0.189453f; - v1 = 0.558594f; - u2 = 0.230469f; - v2 = 0.757813f; - } - - - 95 - { - width = 17; - height = 42; - u1 = 0.234375f; - v1 = 0.558594f; - u2 = 0.283203f; - v2 = 0.757813f; - } - - - 43 - { - width = 22; - height = 42; - u1 = 0.287109f; - v1 = 0.558594f; - u2 = 0.345703f; - v2 = 0.757813f; - } - - - 61 - { - width = 22; - height = 42; - u1 = 0.349609f; - v1 = 0.558594f; - u2 = 0.408203f; - v2 = 0.757813f; - } - - - 45 - { - width = 12; - height = 42; - u1 = 0.412109f; - v1 = 0.558594f; - u2 = 0.451172f; - v2 = 0.757813f; - } - - - 91 - { - width = 13; - height = 42; - u1 = 0.455078f; - v1 = 0.558594f; - u2 = 0.496094f; - v2 = 0.757813f; - } - - - 93 - { - width = 13; - height = 42; - u1 = 0.5f; - v1 = 0.558594f; - u2 = 0.541016f; - v2 = 0.757813f; - } - - - 58 - { - width = 12; - height = 42; - u1 = 0.544922f; - v1 = 0.558594f; - u2 = 0.583984f; - v2 = 0.757813f; - } - - - 59 - { - width = 12; - height = 42; - u1 = 0.587891f; - v1 = 0.558594f; - u2 = 0.626953f; - v2 = 0.757813f; - } - - - 39 - { - width = 10; - height = 42; - u1 = 0.630859f; - v1 = 0.558594f; - u2 = 0.666016f; - v2 = 0.757813f; - } - - - 34 - { - width = 17; - height = 42; - u1 = 0.669922f; - v1 = 0.558594f; - u2 = 0.71875f; - v2 = 0.757813f; - } - - - 44 - { - width = 12; - height = 42; - u1 = 0.722656f; - v1 = 0.558594f; - u2 = 0.761719f; - v2 = 0.757813f; - } - - - 46 - { - width = 12; - height = 42; - u1 = 0.765625f; - v1 = 0.558594f; - u2 = 0.804688f; - v2 = 0.757813f; - } - - - 60 - { - width = 22; - height = 42; - u1 = 0.808594f; - v1 = 0.558594f; - u2 = 0.867188f; - v2 = 0.757813f; - } - - - 62 - { - width = 22; - height = 42; - u1 = 0.871094f; - v1 = 0.558594f; - u2 = 0.929688f; - v2 = 0.757813f; - } - - - 47 - { - width = 10; - height = 42; - u1 = 0.933594f; - v1 = 0.558594f; - u2 = 0.96875f; - v2 = 0.757813f; - } - - - 63 - { - width = 21; - height = 42; - u1 = 0.011719f; - v1 = 0.746094f; - u2 = 0.068359f; - v2 = 0.945313f; - } - - - 92 - { - width = 10; - height = 42; - u1 = 0.072266f; - v1 = 0.746094f; - u2 = 0.107422f; - v2 = 0.945313f; - } - -} - diff --git a/Source/Core/Resources/Font.png b/Source/Core/Resources/Font.png deleted file mode 100644 index c7986dc..0000000 Binary files a/Source/Core/Resources/Font.png and /dev/null differ diff --git a/Source/Core/Windows/IMainForm.cs b/Source/Core/Windows/IMainForm.cs index 0754b00..dad2bd6 100644 --- a/Source/Core/Windows/IMainForm.cs +++ b/Source/Core/Windows/IMainForm.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Windows.Forms; using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Geometry; @@ -76,6 +77,7 @@ namespace CodeImp.DoomBuilder.Windows void ResumeExclusiveMouseInput(); void SetCursor(Cursor cursor); void MessageBeep(MessageBeepType type); + SizeF MeasureString(string text, Font font); //mxd /// /// This moves the focus to the editing display. diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 4169daf..9a5759b 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -173,6 +173,9 @@ namespace CodeImp.DoomBuilder.Windows //mxd private System.Timers.Timer blinkTimer; private bool editformopen; + + //mxd. Misc drawing + private Graphics graphics; #endregion @@ -288,6 +291,9 @@ namespace CodeImp.DoomBuilder.Windows //mxd. Hints hintsPanel = new HintsPanel(); hintsDocker = new Docker("hints", "Help", hintsPanel); + + //mxd. Graphics + graphics = Graphics.FromHwndInternal(windowptr); } #endregion @@ -4231,5 +4237,14 @@ namespace CodeImp.DoomBuilder.Windows } #endregion + + #region ================== Graphics (mxd) + + public SizeF MeasureString(string text, Font font) + { + return graphics.MeasureString(text, font); + } + + #endregion } } \ No newline at end of file diff --git a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs index c7a8283..4797702 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs @@ -367,7 +367,7 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd [BeginAction("togglehighlight")] - public void ToggleHighlight() + public virtual void ToggleHighlight() { BuilderPlug.Me.UseHighlight = !BuilderPlug.Me.UseHighlight; General.Interface.DisplayStatus(StatusType.Action, "Highlight is now " + (BuilderPlug.Me.UseHighlight ? "ON" : "OFF") + "."); diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs index 1374a0f..d25a3e7 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs @@ -138,11 +138,12 @@ namespace CodeImp.DoomBuilder.BuilderModes if(labels != null) { // Dispose old labels - foreach(KeyValuePair lbl in labels) - foreach(TextLabel l in lbl.Value) l.Dispose(); + foreach(TextLabel[] lbl in labels.Values) + foreach(TextLabel l in lbl) l.Dispose(); } // Make text labels for sectors + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Highlight : General.Colors.Selection); //mxd labels = new Dictionary(General.Map.Map.Sectors.Count); foreach(Sector s in General.Map.Map.Sectors) { @@ -151,13 +152,12 @@ namespace CodeImp.DoomBuilder.BuilderModes for(int i = 0; i < s.Labels.Count; i++) { Vector2D v = s.Labels[i].position; - labelarray[i] = new TextLabel(20); + labelarray[i] = new TextLabel(); labelarray[i].TransformCoords = true; labelarray[i].Rectangle = new RectangleF(v.x, v.y, 0.0f, 0.0f); labelarray[i].AlignX = TextAlignmentX.Center; labelarray[i].AlignY = TextAlignmentY.Middle; - labelarray[i].Scale = 14f; - labelarray[i].Color = General.Colors.Highlight.WithAlpha(255); + labelarray[i].Color = c; labelarray[i].Backcolor = General.Colors.Background.WithAlpha(255); } labels.Add(s, labelarray); @@ -192,6 +192,7 @@ namespace CodeImp.DoomBuilder.BuilderModes if(BuilderPlug.Me.ViewSelectionNumbers) { + List torender = new List(orderedselection.Count); foreach(Sector s in orderedselection) { // Render labels @@ -202,9 +203,10 @@ namespace CodeImp.DoomBuilder.BuilderModes // Render only when enough space for the label to see float requiredsize = (l.TextSize.Height / 2) / renderer.Scale; - if(requiredsize < s.Labels[i].radius) renderer.RenderText(l); + if(requiredsize < s.Labels[i].radius) torender.Add(l); } } + renderer.RenderText(torender); } //mxd. Render effect labels @@ -221,9 +223,10 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd private void RenderEffectLabels(Dictionary labelsGroup) { + List torender = new List(labelsGroup.Count); foreach(KeyValuePair group in labelsGroup) { - // Render labels + // Pick which text variant to use TextLabel[] labelarray = labels[group.Key]; for(int i = 0; i < group.Key.Labels.Count; i++) { @@ -231,10 +234,10 @@ namespace CodeImp.DoomBuilder.BuilderModes l.Color = General.Colors.InfoLine; // Render only when enough space for the label to see - float requiredsize = (General.Map.GetTextSize(group.Value[0], l.Scale).Width) / renderer.Scale; + float requiredsize = (General.Interface.MeasureString(group.Value[0], l.Font).Width / 2) / renderer.Scale; if(requiredsize > group.Key.Labels[i].radius) { - requiredsize = (General.Map.GetTextSize(group.Value[1], l.Scale).Width) / renderer.Scale; + requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale; l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]); } else @@ -242,9 +245,12 @@ namespace CodeImp.DoomBuilder.BuilderModes l.Text = group.Value[0]; } - renderer.RenderText(l); + torender.Add(l); } } + + // Render labels + renderer.RenderText(torender); } //mxd @@ -286,8 +292,8 @@ namespace CodeImp.DoomBuilder.BuilderModes string[] result = new[] { string.Empty, string.Empty }; if(s.Effect != 0 && s.Tag != 0) { - result[0] = tagstr + "; " + effectstr; - result[1] = tagstrshort + " " + effectstrshort; + result[0] = tagstr + Environment.NewLine + effectstr; + result[1] = tagstrshort + Environment.NewLine + effectstrshort; } else if(s.Effect != 0) { @@ -413,14 +419,16 @@ namespace CodeImp.DoomBuilder.BuilderModes if((highlighted != null) && !highlighted.IsDisposed) { TextLabel[] labelarray = labels[highlighted]; - foreach(TextLabel l in labelarray) l.Color = General.Colors.Selection; + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Highlight : General.Colors.Selection); + foreach(TextLabel l in labelarray) l.Color = c; } // Change label color if((s != null) && !s.IsDisposed) { TextLabel[] labelarray = labels[s]; - foreach(TextLabel l in labelarray) l.Color = General.Colors.Highlight; + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Selection : General.Colors.Highlight); + foreach(TextLabel l in labelarray) l.Color = c; } // If we're changing associations, then we @@ -485,11 +493,12 @@ namespace CodeImp.DoomBuilder.BuilderModes { //mxd string selectedCount = General.Map.Map.SelectedSectorsCount.ToString(); + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Highlight : General.Colors.Selection); TextLabel[] labelarray = labels[s]; foreach(TextLabel l in labelarray) { l.Text = selectedCount; - l.Color = General.Colors.Selection; + l.Color = c; } UpdateEffectLabels(); @@ -545,6 +554,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Go for all labels in all selected sectors ICollection orderedselection = General.Map.Map.GetSelectedSectors(true); + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Highlight : General.Colors.Selection); //mxd int index = 0; foreach(Sector s in orderedselection) { @@ -554,7 +564,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Make sure the text and color are right int labelnum = index + 1; l.Text = labelnum.ToString(); - l.Color = General.Colors.Selection; + l.Color = c; } index++; } @@ -826,7 +836,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // Update overlay TextLabel[] labelarray = labels[highlighted]; - foreach(TextLabel l in labelarray) l.Color = General.Colors.Highlight; + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Selection : General.Colors.Highlight); + foreach(TextLabel l in labelarray) l.Color = c; UpdateOverlaySurfaces(); //mxd UpdateOverlay(); renderer.Present(); @@ -1333,6 +1344,26 @@ namespace CodeImp.DoomBuilder.BuilderModes base.OnRedoEnd(); //mxd } + //mxd + public override void ToggleHighlight() + { + // Update label colors + PixelColor c = (BuilderPlug.Me.UseHighlight ? General.Colors.Selection : General.Colors.Highlight); + foreach(TextLabel[] labelarray in labels.Values) + foreach(TextLabel l in labelarray) l.Color = c; + + // Update highlighted label color + if((highlighted != null) && !highlighted.IsDisposed) + { + TextLabel[] labelarray = labels[highlighted]; + c = (BuilderPlug.Me.UseHighlight ? General.Colors.Highlight : General.Colors.Selection); + foreach(TextLabel l in labelarray) l.Color = c; + } + + // Pass to base + base.ToggleHighlight(); + } + //mxd private void RenderComment(Sector s) { diff --git a/Source/Plugins/BuilderModes/General/LineLengthLabel.cs b/Source/Plugins/BuilderModes/General/LineLengthLabel.cs index 1ced737..728c7c0 100644 --- a/Source/Plugins/BuilderModes/General/LineLengthLabel.cs +++ b/Source/Plugins/BuilderModes/General/LineLengthLabel.cs @@ -29,8 +29,6 @@ namespace CodeImp.DoomBuilder.BuilderModes { #region ================== Constants - private const int TEXT_CAPACITY = 15; - private const float TEXT_SCALE = 14f; private const string VALUE_FORMAT = "0"; #endregion @@ -105,12 +103,11 @@ namespace CodeImp.DoomBuilder.BuilderModes // Initialization private void Initialize() { - label = new TextLabel(TEXT_CAPACITY); + label = new TextLabel(); label.AlignX = TextAlignmentX.Center; label.AlignY = TextAlignmentY.Middle; label.Color = General.Colors.Highlight; label.Backcolor = General.Colors.Background; - label.Scale = TEXT_SCALE; label.TransformCoords = true; } @@ -133,8 +130,8 @@ namespace CodeImp.DoomBuilder.BuilderModes float length = delta.GetLength(); if(showangle) { - int displayangle = General.ClampAngle((int)Math.Round(Angle2D.RadToDeg(delta.GetAngle())) - 90); - label.Text = "l:" + length.ToString(VALUE_FORMAT) + "; a:" + displayangle; + int displayangle = General.ClampAngle((int)Math.Round(Angle2D.RadToDeg(delta.GetAngle()))); + label.Text = "L:" + length.ToString(VALUE_FORMAT) + "; A:" + displayangle; } else { @@ -194,7 +191,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { Vector2D perpendicular = (end - start).GetPerpendicular(); float angle = perpendicular.GetAngle(); - SizeF textsize = General.Map.GetTextSize(label.Text, label.Scale); + SizeF textsize = General.Interface.MeasureString(label.Text, label.Font); float offset = textsize.Width * Math.Abs((float)Math.Sin(angle)) + textsize.Height * Math.Abs((float)Math.Cos(angle)); perpendicular = perpendicular.GetNormal().GetScaled(offset / 2.0f / General.Map.Renderer2D.Scale); start += perpendicular;