From 500a7711367fa4bbdf0170a3f6403fc5a8632aa7 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Mon, 18 May 2020 23:24:38 +0200 Subject: [PATCH] fixed generic bitmap fonts not calculating character width correctly --- MLEM.Extended/Font/GenericBitmapFont.cs | 17 ++ Sandbox/Content/Content.mgcb | 17 ++ Sandbox/Content/Fonts/Regular.fnt | 330 +++++++++++++++++++++++ Sandbox/Content/Fonts/RegularTexture.png | Bin 0 -> 3575 bytes Sandbox/GameImpl.cs | 18 +- 5 files changed, 375 insertions(+), 7 deletions(-) create mode 100644 Sandbox/Content/Fonts/Regular.fnt create mode 100644 Sandbox/Content/Fonts/RegularTexture.png diff --git a/MLEM.Extended/Font/GenericBitmapFont.cs b/MLEM.Extended/Font/GenericBitmapFont.cs index 2df049a..fb3adc9 100644 --- a/MLEM.Extended/Font/GenericBitmapFont.cs +++ b/MLEM.Extended/Font/GenericBitmapFont.cs @@ -21,10 +21,14 @@ namespace MLEM.Extended.Font { } public override Vector2 MeasureString(string text) { + if (text.Length == 1 && this.SingleCharacterWidthFix(text, out var size)) + return size; return this.Font.MeasureString(text); } public override Vector2 MeasureString(StringBuilder text) { + if (text.Length == 1 && this.SingleCharacterWidthFix(text.ToString(), out var size)) + return size; return this.Font.MeasureString(text); } @@ -52,5 +56,18 @@ namespace MLEM.Extended.Font { batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth); } + // this fixes an issue with BitmapFonts where, if only given a single character, + // only the width of the character itself (disregarding spacing) is returned + private bool SingleCharacterWidthFix(string text, out Vector2 size) { + var codePoint = char.ConvertToUtf32(text, 0); + var region = this.Font.GetCharacterRegion(codePoint); + if (region != null) { + size = new Vector2(region.XAdvance, region.Height); + return true; + } + size = default; + return false; + } + } } \ No newline at end of file diff --git a/Sandbox/Content/Content.mgcb b/Sandbox/Content/Content.mgcb index f637798..b3ff1d0 100644 --- a/Sandbox/Content/Content.mgcb +++ b/Sandbox/Content/Content.mgcb @@ -14,6 +14,23 @@ #---------------------------------- Content ---------------------------------# +#begin Fonts/Regular.fnt +/importer:BitmapFontImporter +/processor:BitmapFontProcessor +/build:Fonts/Regular.fnt + +#begin Fonts/RegularTexture.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Fonts/RegularTexture.png + #begin Fonts/TestFont.spritefont /importer:FontDescriptionImporter /processor:FontDescriptionProcessor diff --git a/Sandbox/Content/Fonts/Regular.fnt b/Sandbox/Content/Fonts/Regular.fnt new file mode 100644 index 0000000..bee2d8c --- /dev/null +++ b/Sandbox/Content/Fonts/Regular.fnt @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sandbox/Content/Fonts/RegularTexture.png b/Sandbox/Content/Fonts/RegularTexture.png new file mode 100644 index 0000000000000000000000000000000000000000..2dbf1701dda350b681a20c5b1557726f88c0c21d GIT binary patch literal 3575 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"Textures/Test"); - var font = new GenericSpriteFont(LoadContent("Fonts/TestFont")); + //var font = new GenericSpriteFont(LoadContent("Fonts/TestFont")); + var font = new GenericBitmapFont(LoadContent("Fonts/Regular")); this.UiSystem.Style = new UntexturedStyle(this.SpriteBatch) { Font = font, TextScale = 0.1F, @@ -116,23 +119,24 @@ namespace Sandbox { var formatter = new TextFormatter(); formatter.AddImage("Test", new TextureRegion(tex, 0, 8, 24, 24)); - //var strg = "This is a formatted string with two bits of formatting! It also includesaverylongwordthatisformattedaswell. Additionally, it wobbles and has a shadow or a weird shadow. We like icons too! "; + var strg = "This is a formatted string with two bits of formatting! It also includesaverylongwordthatisformattedaswell. Additionally, it wobbles and has a shadow or a weird shadow. We like icons too! "; //var strg = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; //var strg = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; - var strg = "This is a test of the underlined formatting code!"; + //var strg = "This is a test of the underlined formatting code!"; this.tokenized = formatter.Tokenize(font, strg); - this.tokenized.Split(font, 400, 1); + this.tokenized.Split(font, 400, 5); this.OnDraw += (g, time) => { - this.SpriteBatch.Begin(); + this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp); this.SpriteBatch.FillRectangle(new RectangleF(400, 20, 400, 1000), Color.Green); - this.tokenized.Draw(time, this.SpriteBatch, new Vector2(400, 20), font, Color.White, 1, 0); + font.DrawString(this.SpriteBatch, this.tokenized.DisplayString, new Vector2(400, 20), Color.White * 0.25F, 0, Vector2.Zero, 5, SpriteEffects.None, 0); + this.tokenized.Draw(time, this.SpriteBatch, new Vector2(400, 20), font, Color.White, 5, 0); this.SpriteBatch.End(); }; this.OnUpdate += (g, time) => { if (this.InputHandler.IsPressed(Keys.W)) { this.tokenized = formatter.Tokenize(font, strg); - this.tokenized.Split(font, this.InputHandler.IsModifierKeyDown(ModifierKey.Shift) ? 400 : 500, 1); + this.tokenized.Split(font, this.InputHandler.IsModifierKeyDown(ModifierKey.Shift) ? 400 : 500, 5); } this.tokenized.Update(time); };