/Rendering/BasicTests/FontTests.cs
C# | 737 lines | 522 code | 78 blank | 137 comment | 37 complexity | 4e55233fee16df54ded4851700d36296 MD5 | raw file
Possible License(s): Apache-2.0
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Text;
- using Delta.ContentSystem.Rendering;
- using Delta.Engine;
- using Delta.InputSystem;
- using Delta.InputSystem.Devices;
- using Delta.Rendering.Basics.Drawing;
- using Delta.Rendering.Basics.Fonts;
- using Delta.Rendering.Basics.Materials;
- using Delta.Rendering.Enums;
- using Delta.Utilities;
- using Delta.Utilities.Datatypes;
- using Delta.Utilities.Datatypes.Advanced;
- using Delta.Utilities.Graphics;
- using Delta.Utilities.Helpers;
- using NUnit.Framework;
-
- namespace Delta.Rendering.BasicTests
- {
- /// <summary>
- /// All unit tests for the Delta.Rendering.Fonts module.
- /// <para />
- /// Reference of "famous" test sentences for bitmap fonts:
- /// http://forums.appleinsider.com/archive/index.php/t-57707.html
- /// </summary>
- public class FontTests
- {
- #region DrawSimpleText (Static)
- /// <summary>
- /// Draw simple text in the center of the screen. Also used as a font
- /// rendering performance test. In both debug and release mode and even
- /// with attached profiler we can reach the max. fps here (10k on my
- /// system in OpenTK, Sandy Bridge 4Ghz, GeForce 480). It gets interesting
- /// when disabling swap buffer, clear and geometry rendering, then the fps
- /// goes up to 1.5 million in release mode and 600 000 fps in debug mode :)
- /// </summary>
- [Test]
- public static void DrawSimpleText()
- {
- Application.Start(delegate
- {
- Font.Default.Draw("Hi there",
- Rectangle.FromCenter(Point.Half, Size.Half));
- });
- }
- #endregion
-
- #region TestTextAlignment (Static)
- /// <summary>
- /// TestTextAlignment with some helper lines, boxes and font map to see
- /// if everything is pixel aligned correctly.
- /// </summary>
- [Test]
- public static void TestTextAlignment()
- {
- Material2D fontMaterial = new Material2D("Verdana_9_16");
-
- Application.Start(delegate
- {
- Line.Draw(Point.Zero, Point.One, Color.Green);
- Material2D.Default.Draw(ScreenSpace.ToQuadraticSpace(
- new Rectangle(0, 0, 10, 10)));
- Font.Default.Draw(
- Application.Window.ViewportPixelWidth + "," +
- Application.Window.ViewportPixelHeight, ScreenSpace.DrawArea);
-
- fontMaterial.Draw(ScreenSpace.ToQuadraticSpace(
- new Rectangle(10, 70, 128, 128)));//test: 113 0 7 12
- });
- }
- #endregion
-
- #region DrawSingleLineTextCentered (Static)
- /// <summary>
- /// Draw single line text centered
- /// </summary>
- [Test]
- public static void DrawSingleLineTextCentered()
- {
- Application.Start(delegate
- {
- Font.Default.Draw("Jackdaws love my big sphinx of quartz.",
- Rectangle.FromCenter(0.5f, 0.5f, 0.2f, 0.2f));
- });
- }
- #endregion
-
- #region DrawSingleLineTextTopLeft (Static)
- /// <summary>
- /// Draw single line text in the top left corner
- /// </summary>
- [Test]
- public static void DrawSingleLineTextTopLeft()
- {
- Application.Start(delegate
- {
- Font.DrawTopLeftInformation("Jackdaws love my big sphinx of quartz.");
- });
- }
- #endregion
-
- #region DrawMultiLineText (Static)
- /// <summary>
- /// Draw multi line text
- /// </summary>
- [Test]
- public static void DrawMultiLineText()
- {
- Font infoFont = new Font(Font.Default,
- HorizontalAlignment.Left, VerticalAlignment.Top);
- Application.Start(delegate
- {
- infoFont.Draw(
- "Jackdaws love my big sphinx of quartz.\n" +
- "But another idiom is:\r\n" +
- "Six big juicy steaks sizzled in a pan as five workmen left the" +
- " quarry.\r" +
- ":)",
- new Rectangle(0.5f, 0.5f, 0.2f, infoFont.LineHeight));
- });
- }
- #endregion
-
- #region MeasureSingleLineText (Static)
- /// <summary>
- /// Measure single line text
- /// </summary>
- [Test]
- public static void MeasureSingleLineText()
- {
- const string Text = "Jackdaws love my big sphinx of quartz.";
- Font infoFont = new Font(Font.Default,
- HorizontalAlignment.Left, VerticalAlignment.Top);
- Point textStartPosition = Point.Half;
-
- Application.Start(delegate
- {
- // Measure the text
- Size textSize = infoFont.Measure(Text);
- // and draw the measured text size
- Rect.DrawOutline(new Rectangle(textStartPosition, textSize),
- Color.Red);
-
- // and additionally the original text to check if the computed text
- // fits with the drawn text too
- infoFont.Draw(Text, new Rectangle(textStartPosition,
- new Size(0.2f, infoFont.LineHeight)));
- });
- }
- #endregion
-
- #region MeasureMultiLineText (Static)
- /// <summary>
- /// Measure multi line text
- /// </summary>
- [Test]
- public static void MeasureMultiLineText()
- {
- string text =
- "Jackdaws love my big sphinx of quartz.\n" +
- "But another idiom is:\r\n" +
- "Six big juicy steaks sizzled in a pan as five workmen left the" +
- " quarry.\r" +
- ":)";
-
- Font infoFont = new Font(Font.Default,
- HorizontalAlignment.Left, VerticalAlignment.Top);
-
- Point textStartPos = new Point(0.2f, 0.4f);
- Application.Start(delegate
- {
- // Measure the text
- Size textSize = infoFont.Measure(text);
- // and draw the measured text size
- Rect.DrawOutline(new Rectangle(textStartPos, textSize), Color.Red);
-
- // and additionally the original text to prove if the computed text
- // fits with the drawn text too
- Size availableTextSize = textSize * 1.25f;
- infoFont.Draw(text, new Rectangle(textStartPos, availableTextSize));
- // and draw also the available text size
- Rect.DrawOutline(new Rectangle(textStartPos, availableTextSize),
- Color.Green);
- });
- }
- #endregion
-
- #region MeasureTab (Static)
- /// <summary>
- /// Measure tab
- /// </summary>
- [Test]
- public static void MeasureTab()
- {
- Font infoFont = new Font(Font.Default,
- HorizontalAlignment.Left, VerticalAlignment.Top);
-
- Point textStartPosition = Point.Half;
- Application.Start(delegate
- {
- // Measure the tab
- Size numberSize = infoFont.Measure("0");
- Size tabSize = infoFont.Measure("\t");
- // and draw the measured text size
- Rectangle tabRectangle = new Rectangle(textStartPosition, tabSize);
- tabRectangle.X += numberSize.Width;
- Rect.DrawOutline(tabRectangle, Color.Red);
-
- // and addionally the tab + some text for better visualization and
- // comparing it
- infoFont.Draw("0\t123456789", new Rectangle(textStartPosition,
- new Size(0.2f, infoFont.LineHeight)));
- // wit normal spaces
- infoFont.Draw("0 1 2 3 456789", new Rectangle(textStartPosition.X,
- textStartPosition.Y + infoFont.LineHeight,
- 0.2f, infoFont.LineHeight));
- });
- }
- #endregion
-
- #region DrawSingleLineTextAligned (Static)
- /// <summary>
- /// Draw single line text aligned
- /// </summary>
- [Test]
- public static void DrawSingleLineTextAligned()
- {
- // Get the number of available horizontal
- int horizontalAlignmentModes =
- EnumHelper.GetCount<HorizontalAlignment>();
- // and vertical alignment modes
- int verticalAlignmentModes =
- EnumHelper.GetCount<VerticalAlignment>();
-
- // Create fonts with every horizontal and vertical alignment mode
- Font[,] fonts =
- new Font[horizontalAlignmentModes, verticalAlignmentModes];
- for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
- {
- for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
- {
- fonts[hModeId, vModeId] = new Font(Font.Default,
- (HorizontalAlignment)hModeId, (VerticalAlignment)vModeId);
- }
- }
-
- Application.Start(delegate
- {
- // Show a text with every possible horizontal and vertical alignment
- for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
- {
- for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
- {
- // While the code for all fonts is the same, the actual rendering
- // will appear at different locations on the screen depending on
- // the current alignment combination.
- Font font = fonts[hModeId, vModeId];
- font.Draw(
- "Text at '" + font.HorizontalAlignment + " " +
- font.VerticalAlignment + "'", ScreenSpace.DrawArea);
- }
- }
- });
- }
- #endregion
-
- #region DrawMultiLineTextAligned (Static)
- /// <summary>
- /// Draw multi line text aligned
- /// </summary>
- [Test]
- public static void DrawMultiLineTextAligned()
- {
- // Get the number of available horizontal
- int horizontalAlignmentModes =
- EnumHelper.GetCount<HorizontalAlignment>();
- // and vertical alignment modes
- int verticalAlignmentModes =
- EnumHelper.GetCount<VerticalAlignment>();
-
- // Create fonts with every horizontal and vertical alignment mode
- Font[,] fonts =
- new Font[horizontalAlignmentModes,verticalAlignmentModes];
- for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
- {
- for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
- {
- fonts[hModeId, vModeId] = new Font(Font.Default,
- (HorizontalAlignment)hModeId, (VerticalAlignment)vModeId);
- }
- }
-
- Application.Start(delegate
- {
- // Draw outline of the area we use to draw all fonts
- Rectangle drawArea = ScreenSpace.DrawArea.ScaleCentered(0.99f);
- Rect.DrawOutline(ScreenSpace.DrawArea, Color.Blue);
-
- // Show a text with every possible horizontal and vertical alignment
- for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
- {
- for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
- {
- // While the code for all fonts is the same, the actual rendering
- // will appear at different locations on the screen depending on
- // the current alignment combination.
- Font font = fonts[hModeId, vModeId];
- string text =
- "This text is in the" + Environment.NewLine +
- font.VerticalAlignment + " " + font.HorizontalAlignment +
- Environment.NewLine + "alignment mode.";
- font.Draw(text, drawArea);
- } // for
- } // for
- });
- }
- #endregion
-
- #region DrawTextClipped (Static)
- /// <summary>
- /// Draw text clipped
- /// </summary>
- [Test]
- public static void DrawTextClipped()
- {
- const string Text = "That text should be only inside red box.";
- Point textAreaPos = new Point(0.2f, 0.45f);
-
- Application.Start(delegate
- {
- Size maxTextSize = Font.Default.Measure(Text);
- Font.Default.Draw(
- Text + "If you are still seeing text outside of the" +
- " shown box,\nthen you know the clipping doesn't work :(",
- new Rectangle(textAreaPos, maxTextSize));
- Rect.DrawOutline(new Rectangle(textAreaPos, maxTextSize), Color.Red);
- });
- }
- #endregion
-
- #region DrawTextWordWrapped (Static)
- /// <summary>
- /// Draw text word wrapped
- /// </summary>
- [Test]
- public static void DrawTextWordWrapped()
- {
- string text = "long loong looong loooong text";
- text += Environment.NewLine + "Newline";
-
- Font infoFont = new Font(Font.Default, Color.White,
- HorizontalAlignment.Left, VerticalAlignment.Top, true);
-
- Rectangle textArea = new Rectangle(0.2f, 0.45f, 0.135f, 0.05f);
- Application.Start(delegate
- {
- infoFont.Draw(text, textArea);
- Rect.DrawOutline(textArea, Color.Red);
-
- BaseMouse mouse = Input.Mouse;
- if (Input.Gestures.IsDrag)
- {
- // Compute the drag movement per tick
- textArea.Size += (Size)(mouse.Movement);
- } // if
- });
- }
- #endregion
-
- #region DrawTextResolutionBased (Static)
- /// <summary>
- /// Draw text resolution based
- /// </summary>
- [Test]
- public static void DrawTextResolutionBased()
- {
- Application.Start(delegate
- {
- string fontInfoText =
- "Current resolution: '" + Settings.Resolution + "'\n" +
- "Current font size: '" + Font.Default.CurrentFontSize + "'";
- Font.Default.Draw(fontInfoText, ScreenSpace.DrawArea);
-
- // Switch the 4 supported font scaling-steps by pressing the numbers
- // 1-4 on the keyboard
- if (Input.Keyboard.IsReleased(InputButton.D1))
- {
- Application.Window.Resize(480, 320);
- } // if
- else if (Input.Keyboard.IsReleased(InputButton.D2))
- {
- Application.Window.Resize(800, 480);
- } // if
- else if (Input.Keyboard.IsReleased(InputButton.D3))
- {
- Application.Window.Resize(1024, 768);
- } // if
- else if (Input.Keyboard.IsReleased(InputButton.D4))
- {
- Application.Window.Resize(1920, 1080);
- } // if
- });
- }
- #endregion
-
- #region RotationResearchTest (Static)
- /// <summary>
- /// Rotation research test
- /// </summary>
- [Test]
- private static void RotationResearchTest()
- {
- Rectangle textArea = new Rectangle(0.5f, 0.5f, 0.2f,
- 0.025f);
-
- Rectangle glyphArea = new Rectangle(0.0f, 0.0f, 0.015f,
- 0.02f);
-
- float rotation = 0.0f;
- //rotation = 1.0f;
- Application.Start(delegate
- {
- // Rotate 10 degree per second
- rotation += 22.5f * Time.Delta;
-
- Rect.DrawOutline(textArea, Color.Red, rotation);
-
- Point startPos = new Point(textArea.Left, textArea.Center.Y);
-
- Point rotationOffset =
- (startPos + new Point(glyphArea.Width / 2.0f, 0.0f)) -
- textArea.Center;
-
- rotationOffset.Rotate(rotation);
-
- Point nextGlyphCenterPoint = textArea.Center + rotationOffset;
-
- Line.Draw(textArea.Center, nextGlyphCenterPoint, Color.Orange);
- //Line.Draw(textArea.Center, textArea.BottomRight, Color.Orange);
-
- Rect.DrawOutline(
- Rectangle.FromCenter(nextGlyphCenterPoint, glyphArea.Size),
- Color.Green,
- rotation);
- });
- }
- #endregion
-
- #region DrawSingleLineRotatedText (Static)
- /// <summary>
- /// Draw single line rotated text
- /// </summary>
- [Test]
- public static void DrawSingleLineRotatedText()
- {
- string text = "Jackdaws love my big sphinx of quartz.";
-
- Rectangle textArea = new Rectangle(0.5f, 0.5f,
- // We don't care about the size, do not clip!
- 0.0f, 0.0f);//0.2f, infoFont.LineHeight);
-
- float rotation = 0.0f;
- Application.Start(delegate
- {
- // Draw reference how the unrotated text should look like
- Font.Default.Draw(text,
- Rectangle.FromCenter(0.5f, 0.25f, 0.25f, 0.25f));
-
- // Rotate 90 degree per second (4 seconds for a full rotation)
- if (Input.Keyboard.IsPressed(InputButton.Shift) == false)
- {
- // Only rotate if Shift is not pressed
- rotation += 90.0f * Time.Delta;
- }
-
- // Helper to see the circle we are rotating around in
- if (Input.Keyboard.IsPressed(InputButton.Space))
- {
- Circle.DrawOutline(new Point(0.5f, 0.5f), 0.2f, Color.Red);
- }
-
- // Helpers to see if text is still sharp at 0, 90, 180 and 270 degrees
- if (Input.Keyboard.IsPressed(InputButton.A))
- {
- rotation = 0;
- }
- else if (Input.Keyboard.IsPressed(InputButton.B))
- {
- rotation = 90;
- }
- else if (Input.Keyboard.IsPressed(InputButton.C))
- {
- rotation = 180;
- }
- else if (Input.Keyboard.IsPressed(InputButton.D))
- {
- rotation = 270;
- }
-
- Font.Default.Draw(text, textArea, rotation, Point.Zero);
- });
- }
- #endregion
-
- #region CompareFontKerning (LongRunning)
- /// <summary>
- /// Compare font kerning
- /// </summary>
- [Test, Category("LongRunning")]
- public static void CompareFontKerning()
- {
- // First define the fonts
- Font noKerningFont = new Font(
- FontData.Get("VerdanaNoKerning", 28, FontStyle.AddOutline),
- HorizontalAlignment.Left);
- Font kerningFont = new Font(
- FontData.Get("Verdana", 28, FontStyle.AddOutline),
- HorizontalAlignment.Left);
-
- // As next the text we want to see with and without kerning
- const string Text = "P. and V.";
-
- // also the text area (reference) for the text drawing
- Rectangle textArea = new Rectangle(0.5f, 0.4f, 0.3f,
- kerningFont.LineHeight);
- Application.Start(delegate
- {
- // Now just show the text without kerning
- noKerningFont.Draw("Without kerning: ", textArea.Move(-0.3f, 0.0f));
- noKerningFont.Draw(Text, textArea);
-
- // And once with kerning to see the difference
- noKerningFont.Draw("With kerning: ", textArea.Move(-0.3f,
- kerningFont.LineHeight));
- kerningFont.Draw(Text, textArea.Move(0.0f,
- kerningFont.LineHeight));
- });
- }
- #endregion
-
- #region DrawMultiLineRotatedText (LongRunning)
- /// <summary>
- /// Draw multi line rotated text
- /// </summary>
- [Test, Category("LongRunning")]
- public static void DrawMultiLineRotatedText()
- {
- string text =
- "Jackdaws love my big sphinx of quartz.\n" +
- "But another idiom is:\r\n" +
- "Six big juicy steaks sizzled.";
-
- Rectangle textArea =
- new Rectangle(0.35f, 0.25f, 0.3f, Font.Default.LineHeight * 3.0f);
-
- float rotation = 0.0f;
- Application.Start(delegate
- {
- // Draw reference how the unrotated text should look like
- Font.Default.Draw(text, textArea, 0.0f, Point.Zero);
-
- // Rotate 90 degree per second
- rotation += 90.0f * Time.Delta;
-
- Font.Default.Draw(text, textArea.Move(0.0f, 0.25f), rotation,
- Point.Zero);
- });
- }
- #endregion
-
- #region DrawPerformanceTest
- /// <summary>
- /// Draw performance test
- /// </summary>
- [Test, Category("Visual")]
- public static void DrawPerformanceTest()
- {
- string[] texts = new[]
- {
- "Hello World",
- " !\"#$%&'()*+,-./0123456789:;<=>?@",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`",
- "abcdefghijklmnopqrstuvwxyz{|}~",
- "That kind of drawing text is interresting.",
- "Hello World"
- };
-
- Font infoFont = new Font(Font.Default,
- HorizontalAlignment.Left, VerticalAlignment.Top);
-
- Size textSize = new Size(1.0f, infoFont.LineHeight * 3);
- Application.Start(delegate
- {
-
- for (int index = 0; index < texts.Length; index++)
- {
- Rectangle textArea = new Rectangle(
- new Point(0.1f, 0.2f + index * infoFont.LineHeight * 2.5f),
- textSize);
-
- // old: Judge: Win 7, Core i7 920, 6 GB Ram, Ati 5750 HD
- // - Draw with GlyphInfo[] -> ~2540 FPS
- // - Draw with Geometry -> ~3170 FPS
-
- // Optimized to ~10000 FPS on Sandy Bridge 4Ghz, GeForce 480.
- // without swapbuffer/clear/render this is ~250000 FPS (in debug
- // mode, in release mode we can reach 3 times that)
-
- // Drawing by cached glyph info's
- infoFont.Draw(texts[index], textArea, 0.0f, Point.Zero);
-
- // on the mobile devices
- //// Drawing by cached geomtry
- //infoFont.Draw(texts[index], textArea, 0.0f, Point.Zero);
- }
-
- //no thanks to auto quit
- //if (Time.Seconds >= 3)
- //{
- // Application.Quit();
- //} // if
- });
- }
- #endregion
-
- #region TestCharCollectingPerformance (Static)
- /// <summary>
- /// Test char collecting
- /// </summary>
- [Test]
- private static void TestCharCollectingPerformance()
- {
- string text = "ehoiwrhaenf ierfh ioei hEWOIHoeirjnlsdnflsdn osdjfsdfö " +
- "ashnfdeir aweho nklidfhwioerhoewir knskdfla jrfweimwaemfijefe ids " +
- "löginjaqw ioiai wrjnuiu na ua safooiuroiwrpewr jioa djijwrweruqwer" +
- "iodjpjanvlxic9prtgopüaj opdu 39483 rawü ß asd 0po asd ak lkjdfau80" +
- "ok09i2jqaw 9 9a du opjo34eqwrjfaj oas parörpo3ir0 wakasj ööas foMF" +
- "esifjhaierf idsfj lijef iodsfjinnhdf dfhhidsio idinqäppa osao oad";
-
- int Loops = 100000;
-
- char[] textChars = text.ToCharArray();
-
- Stopwatch time = new Stopwatch();
-
- List<char> charList = new List<char>();
- time.Start();
- for (int i = 0; i < Loops; i++)
- {
- for (int charId = 0; charId < textChars.Length; charId++)
- {
- charList.Add(textChars[charId]);
- }
- charList.Clear();
- }
- time.Stop();
- Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
-
- string charString = "";
- time.Restart();
- for (int i = 0; i < Loops; i++)
- {
- for (int charId = 0; charId < textChars.Length; charId++)
- {
- charString += textChars[charId];
- }
- charString = "";
- }
- time.Stop();
- Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
-
- StringBuilder charBuilder = new StringBuilder();
- time.Restart();
- for (int i = 0; i < Loops; i++)
- {
- for (int charId = 0; charId < textChars.Length; charId++)
- {
- charBuilder.Append(textChars[charId]);
- }
- charBuilder.Clear();
- }
- time.Stop();
- Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
-
- List<char> list = new List<char>();
- time.Restart();
- for (int i = 0; i < Loops; i++)
- {
- char[] chars = text.ToCharArray();
- for (int charId = 0; charId < chars.Length; charId++)
- {
- list.Add(chars[charId]);
- }
- charString = "";
- }
- time.Stop();
- Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
-
- list = new List<char>();
- time.Restart();
- for (int i = 0; i < Loops; i++)
- {
- for (int charId = 0; charId < text.Length; charId++)
- {
- list.Add(text[charId]);
- }
- charString = "";
- }
- time.Stop();
- Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
- }
- #endregion
-
- #region TestFontRamBug (Static)
- /// <summary>
- /// Test the bug #4015 with massively increasing ram as posted here:
- /// http://forum.deltaengine.net/yaf_postsm851_-Bug--Or-WTF-RAM-Faill.aspx#post851
- /// </summary>
- [Test]
- public static void TestFontRamBug()
- {
- int tmp = 0;
- string inputText;
- Application.Start(delegate
- {
- // Constantly change the text to be rendered.
- tmp++;
- inputText = "Level1 \n" + tmp;
- Font.Default.Draw(inputText, new Rectangle(0.025f, 0.45f, 0.3f, 0.3f));
- });
- }
- #endregion
- }
- }
-