PageRenderTime 182ms CodeModel.GetById 51ms app.highlight 50ms RepoModel.GetById 53ms app.codeStats 1ms

/Rendering/BasicTests/FontTests.cs

#
C# | 737 lines | 522 code | 78 blank | 137 comment | 37 complexity | 4e55233fee16df54ded4851700d36296 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Diagnostics;
  4using System.Text;
  5using Delta.ContentSystem.Rendering;
  6using Delta.Engine;
  7using Delta.InputSystem;
  8using Delta.InputSystem.Devices;
  9using Delta.Rendering.Basics.Drawing;
 10using Delta.Rendering.Basics.Fonts;
 11using Delta.Rendering.Basics.Materials;
 12using Delta.Rendering.Enums;
 13using Delta.Utilities;
 14using Delta.Utilities.Datatypes;
 15using Delta.Utilities.Datatypes.Advanced;
 16using Delta.Utilities.Graphics;
 17using Delta.Utilities.Helpers;
 18using NUnit.Framework;
 19
 20namespace Delta.Rendering.BasicTests
 21{
 22	/// <summary>
 23	/// All unit tests for the Delta.Rendering.Fonts module.
 24	/// <para />
 25	/// Reference of "famous" test sentences for bitmap fonts:
 26	/// http://forums.appleinsider.com/archive/index.php/t-57707.html
 27	/// </summary>
 28	public class FontTests
 29	{
 30		#region DrawSimpleText (Static)
 31		/// <summary>
 32		/// Draw simple text in the center of the screen. Also used as a font
 33		/// rendering performance test. In both debug and release mode and even
 34		/// with attached profiler we can reach the max. fps here (10k on my
 35		/// system in OpenTK, Sandy Bridge 4Ghz, GeForce 480). It gets interesting
 36		/// when disabling swap buffer, clear and geometry rendering, then the fps
 37		/// goes up to 1.5 million in release mode and 600 000 fps in debug mode :)
 38		/// </summary>
 39		[Test]
 40		public static void DrawSimpleText()
 41		{
 42			Application.Start(delegate
 43			{
 44				Font.Default.Draw("Hi there",
 45					Rectangle.FromCenter(Point.Half, Size.Half));
 46			});
 47		}
 48		#endregion
 49
 50		#region TestTextAlignment (Static)
 51		/// <summary>
 52		/// TestTextAlignment with some helper lines, boxes and font map to see
 53		/// if everything is pixel aligned correctly.
 54		/// </summary>
 55		[Test]
 56		public static void TestTextAlignment()
 57		{
 58			Material2D fontMaterial = new Material2D("Verdana_9_16");
 59
 60			Application.Start(delegate
 61			{
 62				Line.Draw(Point.Zero, Point.One, Color.Green);
 63				Material2D.Default.Draw(ScreenSpace.ToQuadraticSpace(
 64					new Rectangle(0, 0, 10, 10)));
 65				Font.Default.Draw(
 66					Application.Window.ViewportPixelWidth + "," +
 67					Application.Window.ViewportPixelHeight, ScreenSpace.DrawArea);
 68
 69				fontMaterial.Draw(ScreenSpace.ToQuadraticSpace(
 70					new Rectangle(10, 70, 128, 128)));//test: 113 0 7 12
 71			});
 72		}
 73		#endregion
 74
 75		#region DrawSingleLineTextCentered (Static)
 76		/// <summary>
 77		/// Draw single line text centered
 78		/// </summary>
 79		[Test]
 80		public static void DrawSingleLineTextCentered()
 81		{
 82			Application.Start(delegate
 83			{
 84				Font.Default.Draw("Jackdaws love my big sphinx of quartz.",
 85					Rectangle.FromCenter(0.5f, 0.5f, 0.2f, 0.2f));
 86			});
 87		}
 88		#endregion
 89
 90		#region DrawSingleLineTextTopLeft (Static)
 91		/// <summary>
 92		/// Draw single line text in the top left corner
 93		/// </summary>
 94		[Test]
 95		public static void DrawSingleLineTextTopLeft()
 96		{
 97			Application.Start(delegate
 98			{
 99				Font.DrawTopLeftInformation("Jackdaws love my big sphinx of quartz.");
100			});
101		}
102		#endregion
103
104		#region DrawMultiLineText (Static)
105		/// <summary>
106		/// Draw multi line text
107		/// </summary>
108		[Test]
109		public static void DrawMultiLineText()
110		{
111			Font infoFont = new Font(Font.Default,
112				HorizontalAlignment.Left, VerticalAlignment.Top);
113			Application.Start(delegate
114			{
115				infoFont.Draw(
116					"Jackdaws love my big sphinx of quartz.\n" +
117					"But another idiom is:\r\n" +
118					"Six big juicy steaks sizzled in a pan as five workmen left the" +
119					" quarry.\r" +
120					":)",
121					new Rectangle(0.5f, 0.5f, 0.2f, infoFont.LineHeight));
122			});
123		}
124		#endregion
125
126		#region MeasureSingleLineText (Static)
127		/// <summary>
128		/// Measure single line text
129		/// </summary>
130		[Test]
131		public static void MeasureSingleLineText()
132		{
133			const string Text = "Jackdaws love my big sphinx of quartz.";
134			Font infoFont = new Font(Font.Default,
135				HorizontalAlignment.Left, VerticalAlignment.Top);
136			Point textStartPosition = Point.Half;
137
138			Application.Start(delegate
139			{
140				// Measure the text
141				Size textSize = infoFont.Measure(Text);
142				// and draw the measured text size
143				Rect.DrawOutline(new Rectangle(textStartPosition, textSize),
144					Color.Red);
145
146				// and additionally the original text to check if the computed text
147				// fits with the drawn text too
148				infoFont.Draw(Text, new Rectangle(textStartPosition,
149					new Size(0.2f, infoFont.LineHeight)));
150			});
151		}
152		#endregion
153
154		#region MeasureMultiLineText (Static)
155		/// <summary>
156		/// Measure multi line text
157		/// </summary>
158		[Test]
159		public static void MeasureMultiLineText()
160		{
161			string text =
162				"Jackdaws love my big sphinx of quartz.\n" +
163				"But another idiom is:\r\n" +
164				"Six big juicy steaks sizzled in a pan as five workmen left the" +
165				" quarry.\r" +
166				":)";
167
168			Font infoFont = new Font(Font.Default,
169				HorizontalAlignment.Left, VerticalAlignment.Top);
170
171			Point textStartPos = new Point(0.2f, 0.4f);
172			Application.Start(delegate
173			{
174				// Measure the text
175				Size textSize = infoFont.Measure(text);
176				// and draw the measured text size
177				Rect.DrawOutline(new Rectangle(textStartPos, textSize), Color.Red);
178
179				// and additionally the original text to prove if the computed text
180				// fits with the drawn text too
181				Size availableTextSize = textSize * 1.25f;
182				infoFont.Draw(text, new Rectangle(textStartPos, availableTextSize));
183				// and draw also the available text size
184				Rect.DrawOutline(new Rectangle(textStartPos, availableTextSize),
185					Color.Green);
186			});
187		}
188		#endregion
189
190		#region MeasureTab (Static)
191		/// <summary>
192		/// Measure tab
193		/// </summary>
194		[Test]
195		public static void MeasureTab()
196		{
197			Font infoFont = new Font(Font.Default, 
198				HorizontalAlignment.Left, VerticalAlignment.Top);
199
200			Point textStartPosition = Point.Half;
201			Application.Start(delegate
202			{
203				// Measure the tab
204				Size numberSize = infoFont.Measure("0");
205				Size tabSize = infoFont.Measure("\t");
206				// and draw the measured text size
207				Rectangle tabRectangle = new Rectangle(textStartPosition, tabSize);
208				tabRectangle.X += numberSize.Width;
209				Rect.DrawOutline(tabRectangle, Color.Red);
210
211				// and addionally the tab + some text for better visualization and
212				// comparing it
213				infoFont.Draw("0\t123456789", new Rectangle(textStartPosition,
214					new Size(0.2f, infoFont.LineHeight)));
215				// wit normal spaces
216				infoFont.Draw("0 1 2 3 456789", new Rectangle(textStartPosition.X,
217					textStartPosition.Y + infoFont.LineHeight,
218					0.2f, infoFont.LineHeight));
219			});
220		}
221		#endregion
222
223		#region DrawSingleLineTextAligned (Static)
224		/// <summary>
225		/// Draw single line text aligned
226		/// </summary>
227		[Test]
228		public static void DrawSingleLineTextAligned()
229		{
230			// Get the number of available horizontal
231			int horizontalAlignmentModes =
232				EnumHelper.GetCount<HorizontalAlignment>();
233			// and vertical alignment modes
234			int verticalAlignmentModes =
235				EnumHelper.GetCount<VerticalAlignment>();
236
237			// Create fonts with every horizontal and vertical alignment mode
238			Font[,] fonts =
239				new Font[horizontalAlignmentModes, verticalAlignmentModes];
240			for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
241			{
242				for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
243				{
244					fonts[hModeId, vModeId] = new Font(Font.Default,
245						(HorizontalAlignment)hModeId, (VerticalAlignment)vModeId);
246				}
247			}
248
249			Application.Start(delegate
250			{
251				// Show a text with every possible horizontal and vertical alignment
252				for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
253				{
254					for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
255					{
256						// While the code for all fonts is the same, the actual rendering
257						// will appear at different locations on the screen depending on
258						// the current alignment combination.
259						Font font = fonts[hModeId, vModeId];
260						font.Draw(
261							"Text at '" + font.HorizontalAlignment + " " +
262							font.VerticalAlignment + "'", ScreenSpace.DrawArea);
263					}
264				}
265			});
266		}
267		#endregion
268
269		#region DrawMultiLineTextAligned (Static)
270		/// <summary>
271		/// Draw multi line text aligned
272		/// </summary>
273		[Test]
274		public static void DrawMultiLineTextAligned()
275		{
276			// Get the number of available horizontal
277			int horizontalAlignmentModes =
278				EnumHelper.GetCount<HorizontalAlignment>();
279			// and vertical alignment modes
280			int verticalAlignmentModes =
281				EnumHelper.GetCount<VerticalAlignment>();
282
283			// Create fonts with every horizontal and vertical alignment mode
284			Font[,] fonts =
285				new Font[horizontalAlignmentModes,verticalAlignmentModes];
286			for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
287			{
288				for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
289				{
290					fonts[hModeId, vModeId] = new Font(Font.Default,
291						(HorizontalAlignment)hModeId, (VerticalAlignment)vModeId);
292				}
293			}
294
295			Application.Start(delegate
296			{
297				// Draw outline of the area we use to draw all fonts
298				Rectangle drawArea = ScreenSpace.DrawArea.ScaleCentered(0.99f);
299				Rect.DrawOutline(ScreenSpace.DrawArea, Color.Blue);
300
301				// Show a text with every possible horizontal and vertical alignment
302				for (int hModeId = 0; hModeId < horizontalAlignmentModes; hModeId++)
303				{
304					for (int vModeId = 0; vModeId < verticalAlignmentModes; vModeId++)
305					{
306						// While the code for all fonts is the same, the actual rendering
307						// will appear at different locations on the screen depending on
308						// the current alignment combination.
309						Font font = fonts[hModeId, vModeId];
310						string text =
311							"This text is in the" + Environment.NewLine +
312							font.VerticalAlignment + " " + font.HorizontalAlignment +
313							Environment.NewLine + "alignment mode.";
314						font.Draw(text, drawArea);
315					} // for
316				} // for
317			});
318		}
319		#endregion
320
321		#region DrawTextClipped (Static)
322		/// <summary>
323		/// Draw text clipped
324		/// </summary>
325		[Test]
326		public static void DrawTextClipped()
327		{
328			const string Text = "That text should be only inside red box.";
329			Point textAreaPos = new Point(0.2f, 0.45f);
330
331			Application.Start(delegate
332			{
333				Size maxTextSize = Font.Default.Measure(Text);
334				Font.Default.Draw(
335					Text + "If you are still seeing text outside of the" +
336					" shown box,\nthen you know the clipping doesn't work :(",
337					new Rectangle(textAreaPos, maxTextSize));
338				Rect.DrawOutline(new Rectangle(textAreaPos, maxTextSize), Color.Red);
339			});
340		}
341		#endregion
342
343		#region DrawTextWordWrapped (Static)
344		/// <summary>
345		/// Draw text word wrapped
346		/// </summary>
347		[Test]
348		public static void DrawTextWordWrapped()
349		{
350			string text = "long loong looong loooong text";
351			text += Environment.NewLine + "Newline";
352
353			Font infoFont = new Font(Font.Default, Color.White,
354				HorizontalAlignment.Left, VerticalAlignment.Top, true);
355
356			Rectangle textArea = new Rectangle(0.2f, 0.45f, 0.135f, 0.05f);
357			Application.Start(delegate
358			{
359				infoFont.Draw(text, textArea);
360				Rect.DrawOutline(textArea, Color.Red);
361
362				BaseMouse mouse = Input.Mouse;
363				if (Input.Gestures.IsDrag)
364				{
365					// Compute the drag movement per tick
366					textArea.Size += (Size)(mouse.Movement);
367				} // if
368			});
369		}
370		#endregion
371
372		#region DrawTextResolutionBased (Static)
373		/// <summary>
374		/// Draw text resolution based
375		/// </summary>
376		[Test]
377		public static void DrawTextResolutionBased()
378		{
379			Application.Start(delegate
380			{
381				string fontInfoText =
382					"Current resolution: '" + Settings.Resolution + "'\n" +
383					"Current font size: '" + Font.Default.CurrentFontSize + "'";
384				Font.Default.Draw(fontInfoText, ScreenSpace.DrawArea);
385
386				// Switch the 4 supported font scaling-steps by pressing the numbers
387				// 1-4 on the keyboard
388				if (Input.Keyboard.IsReleased(InputButton.D1))
389				{
390					Application.Window.Resize(480, 320);
391				} // if
392				else if (Input.Keyboard.IsReleased(InputButton.D2))
393				{
394					Application.Window.Resize(800, 480);
395				} // if
396				else if (Input.Keyboard.IsReleased(InputButton.D3))
397				{
398					Application.Window.Resize(1024, 768);
399				} // if
400				else if (Input.Keyboard.IsReleased(InputButton.D4))
401				{
402					Application.Window.Resize(1920, 1080);
403				} // if
404			});
405		}
406		#endregion
407
408		#region RotationResearchTest (Static)
409		/// <summary>
410		/// Rotation research test
411		/// </summary>
412		[Test]
413		private static void RotationResearchTest()
414		{
415			Rectangle textArea = new Rectangle(0.5f, 0.5f, 0.2f,
416				0.025f);
417
418			Rectangle glyphArea = new Rectangle(0.0f, 0.0f, 0.015f,
419				0.02f);
420
421			float rotation = 0.0f;
422			//rotation = 1.0f;
423			Application.Start(delegate
424			{
425				// Rotate 10 degree per second
426				rotation += 22.5f * Time.Delta;
427
428				Rect.DrawOutline(textArea, Color.Red, rotation);
429
430				Point startPos = new Point(textArea.Left, textArea.Center.Y);
431
432				Point rotationOffset =
433					(startPos + new Point(glyphArea.Width / 2.0f, 0.0f)) -
434					textArea.Center;
435
436				rotationOffset.Rotate(rotation);
437
438				Point nextGlyphCenterPoint = textArea.Center + rotationOffset;
439
440				Line.Draw(textArea.Center, nextGlyphCenterPoint, Color.Orange);
441				//Line.Draw(textArea.Center, textArea.BottomRight, Color.Orange);
442
443				Rect.DrawOutline(
444					Rectangle.FromCenter(nextGlyphCenterPoint, glyphArea.Size),
445					Color.Green,
446					rotation);
447			});
448		}
449		#endregion
450
451		#region DrawSingleLineRotatedText (Static)
452		/// <summary>
453		/// Draw single line rotated text
454		/// </summary>
455		[Test]
456		public static void DrawSingleLineRotatedText()
457		{
458			string text = "Jackdaws love my big sphinx of quartz.";
459
460			Rectangle textArea = new Rectangle(0.5f, 0.5f,
461				// We don't care about the size, do not clip!
462				0.0f, 0.0f);//0.2f, infoFont.LineHeight);
463
464			float rotation = 0.0f;
465			Application.Start(delegate
466			{
467				// Draw reference how the unrotated text should look like
468				Font.Default.Draw(text,
469					Rectangle.FromCenter(0.5f, 0.25f, 0.25f, 0.25f));
470
471				// Rotate 90 degree per second (4 seconds for a full rotation)
472				if (Input.Keyboard.IsPressed(InputButton.Shift) == false)
473				{
474					// Only rotate if Shift is not pressed
475					rotation += 90.0f * Time.Delta;
476				}
477
478				// Helper to see the circle we are rotating around in
479				if (Input.Keyboard.IsPressed(InputButton.Space))
480				{
481					Circle.DrawOutline(new Point(0.5f, 0.5f), 0.2f, Color.Red);
482				}
483
484				// Helpers to see if text is still sharp at 0, 90, 180 and 270 degrees
485				if (Input.Keyboard.IsPressed(InputButton.A))
486				{
487					rotation = 0;
488				}
489				else if (Input.Keyboard.IsPressed(InputButton.B))
490				{
491					rotation = 90;
492				}
493				else if (Input.Keyboard.IsPressed(InputButton.C))
494				{
495					rotation = 180;
496				}
497				else if (Input.Keyboard.IsPressed(InputButton.D))
498				{
499					rotation = 270;
500				}
501
502				Font.Default.Draw(text, textArea, rotation, Point.Zero);
503			});
504		}
505		#endregion
506
507		#region CompareFontKerning (LongRunning)
508		/// <summary>
509		/// Compare font kerning
510		/// </summary>
511		[Test, Category("LongRunning")]
512		public static void CompareFontKerning()
513		{
514			// First define the fonts
515			Font noKerningFont = new Font(
516				FontData.Get("VerdanaNoKerning", 28, FontStyle.AddOutline),
517				HorizontalAlignment.Left);
518			Font kerningFont = new Font(
519				FontData.Get("Verdana", 28, FontStyle.AddOutline),
520				HorizontalAlignment.Left);
521
522			// As next the text we want to see with and without kerning
523			const string Text = "P. and V.";
524
525			// also the text area (reference) for the text drawing
526			Rectangle textArea = new Rectangle(0.5f, 0.4f, 0.3f,
527				kerningFont.LineHeight);
528			Application.Start(delegate
529			{
530				// Now just show the text without kerning
531				noKerningFont.Draw("Without kerning: ", textArea.Move(-0.3f, 0.0f));
532				noKerningFont.Draw(Text, textArea);
533
534				// And once with kerning to see the difference
535				noKerningFont.Draw("With kerning: ", textArea.Move(-0.3f,
536					kerningFont.LineHeight));
537				kerningFont.Draw(Text, textArea.Move(0.0f,
538					kerningFont.LineHeight));
539			});
540		}
541		#endregion
542
543		#region DrawMultiLineRotatedText (LongRunning)
544		/// <summary>
545		/// Draw multi line rotated text
546		/// </summary>
547		[Test, Category("LongRunning")]
548		public static void DrawMultiLineRotatedText()
549		{
550			string text =
551				"Jackdaws love my big sphinx of quartz.\n" +
552				"But another idiom is:\r\n" +
553				"Six big juicy steaks sizzled.";
554
555			Rectangle textArea =
556				new Rectangle(0.35f, 0.25f, 0.3f, Font.Default.LineHeight * 3.0f);
557
558			float rotation = 0.0f;
559			Application.Start(delegate
560			{
561				// Draw reference how the unrotated text should look like
562				Font.Default.Draw(text, textArea, 0.0f, Point.Zero);
563
564				// Rotate 90 degree per second
565				rotation += 90.0f * Time.Delta;
566
567				Font.Default.Draw(text, textArea.Move(0.0f, 0.25f), rotation,
568					Point.Zero);
569			});
570		}
571		#endregion
572
573		#region DrawPerformanceTest
574		/// <summary>
575		/// Draw performance test
576		/// </summary>
577		[Test, Category("Visual")]
578		public static void DrawPerformanceTest()
579		{
580			string[] texts = new[]
581			{
582				"Hello World",
583				" !\"#$%&'()*+,-./0123456789:;<=>?@",
584				"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`",
585				"abcdefghijklmnopqrstuvwxyz{|}~",
586				"That kind of drawing text is interresting.",
587				"Hello World"
588			};
589
590			Font infoFont = new Font(Font.Default,
591				HorizontalAlignment.Left, VerticalAlignment.Top);
592
593			Size textSize = new Size(1.0f, infoFont.LineHeight * 3);
594			Application.Start(delegate
595			{
596
597				for (int index = 0; index < texts.Length; index++)
598				{
599					Rectangle textArea = new Rectangle(
600						new Point(0.1f, 0.2f + index * infoFont.LineHeight * 2.5f),
601						textSize);
602
603					// old: Judge: Win 7, Core i7 920, 6 GB Ram, Ati 5750 HD
604					// - Draw with GlyphInfo[] -> ~2540 FPS
605					// - Draw with Geometry -> ~3170 FPS
606
607					// Optimized to ~10000 FPS on Sandy Bridge 4Ghz, GeForce 480.
608					// without swapbuffer/clear/render this is ~250000 FPS (in debug
609					// mode, in release mode we can reach 3 times that)
610
611					// Drawing by cached glyph info's
612					infoFont.Draw(texts[index], textArea, 0.0f, Point.Zero);
613
614					//				on the mobile devices
615					//// Drawing by cached geomtry
616					//infoFont.Draw(texts[index], textArea, 0.0f, Point.Zero);
617				}
618
619				//no thanks to auto quit
620				//if (Time.Seconds >= 3)
621				//{
622				//  Application.Quit();
623				//} // if
624			});
625		}
626		#endregion
627
628		#region TestCharCollectingPerformance (Static)
629		/// <summary>
630		/// Test char collecting
631		/// </summary>
632		[Test]
633		private static void TestCharCollectingPerformance()
634		{
635			string text = "ehoiwrhaenf ierfh ioei hEWOIHoeirjnlsdnflsdn osdjfsdfö " +
636			              "ashnfdeir aweho nklidfhwioerhoewir knskdfla jrfweimwaemfijefe ids " +
637			              "löginjaqw ioiai wrjnuiu na ua safooiuroiwrpewr jioa djijwrweruqwer" +
638			              "iodjpjanvlxic9prtgopüaj opdu 39483 rawü ß asd 0po asd ak lkjdfau80" +
639			              "ok09i2jqaw 9 9a du opjo34eqwrjfaj oas parörpo3ir0 wakasj ööas foMF" +
640			              "esifjhaierf idsfj lijef iodsfjinnhdf dfhhidsio idinqäppa osao oad";
641
642			int Loops = 100000;
643
644			char[] textChars = text.ToCharArray();
645
646			Stopwatch time = new Stopwatch();
647
648			List<char> charList = new List<char>();
649			time.Start();
650			for (int i = 0; i < Loops; i++)
651			{
652				for (int charId = 0; charId < textChars.Length; charId++)
653				{
654					charList.Add(textChars[charId]);
655				}
656				charList.Clear();
657			}
658			time.Stop();
659			Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
660
661			string charString = "";
662			time.Restart();
663			for (int i = 0; i < Loops; i++)
664			{
665				for (int charId = 0; charId < textChars.Length; charId++)
666				{
667					charString += textChars[charId];
668				}
669				charString = "";
670			}
671			time.Stop();
672			Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
673
674			StringBuilder charBuilder = new StringBuilder();
675			time.Restart();
676			for (int i = 0; i < Loops; i++)
677			{
678				for (int charId = 0; charId < textChars.Length; charId++)
679				{
680					charBuilder.Append(textChars[charId]);
681				}
682				charBuilder.Clear();
683			}
684			time.Stop();
685			Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
686
687			List<char> list = new List<char>();
688			time.Restart();
689			for (int i = 0; i < Loops; i++)
690			{
691				char[] chars = text.ToCharArray();
692				for (int charId = 0; charId < chars.Length; charId++)
693				{
694					list.Add(chars[charId]);
695				}
696				charString = "";
697			}
698			time.Stop();
699			Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
700
701			list = new List<char>();
702			time.Restart();
703			for (int i = 0; i < Loops; i++)
704			{
705				for (int charId = 0; charId < text.Length; charId++)
706				{
707					list.Add(text[charId]);
708				}
709				charString = "";
710			}
711			time.Stop();
712			Log.Info("'" + time.ElapsedMilliseconds + "' ms elapsed.");
713		}
714		#endregion
715
716		#region TestFontRamBug (Static)
717		/// <summary>
718		/// Test the bug #4015 with massively increasing ram as posted here:
719		/// http://forum.deltaengine.net/yaf_postsm851_-Bug--Or-WTF-RAM-Faill.aspx#post851
720		/// </summary>
721		[Test]
722		public static void TestFontRamBug()
723		{
724			int tmp = 0;
725			string inputText;
726			Application.Start(delegate
727			{
728				// Constantly change the text to be rendered.
729				tmp++;
730				inputText = "Level1 \n" + tmp;
731				Font.Default.Draw(inputText, new Rectangle(0.025f, 0.45f, 0.3f, 0.3f));
732			});
733		}
734		#endregion
735	}
736}
737