Last active
November 27, 2018 19:40
-
-
Save stromkos/afaf6bebe0d3bd03737177aa0974be7f to your computer and use it in GitHub Desktop.
Monogame runtime Android renderer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
License | |
MS-PL | |
Usage: | |
Add using AndroidTextDraw; | |
in your Draw method: | |
spriteBatch.DrawText(24, "Hello World 👋", new Vector2(10, 10), Color.White, Color.CornflowerBlue); | |
in the UnloadContent method: | |
spriteBatch.ClearCache(); or AndroidDrawExtension.ClearCache(); | |
Notes: | |
Uses the default system font. Can be changed in line 72. | |
Emojis are rendered in color(Always pass Color.White as first color argument) | |
This uses a Dictionary to cache the textures, to speed up reuse. | |
If you pass a backgroud color with transparency, your text will not be anti-aliased | |
Changing the Position parameter type to Rectangle will scale the Text to fit( with possible aspect ratio stretching) | |
----- | |
If you wish to manage the Textures yourself, use GetDrawText | |
This can be called from anywhere spriteBatch exists( in and after LoadContent). | |
Be sure to dispose of the created textures to prevent memory leaks. | |
--- | |
*/ | |
using Android.Graphics; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using System.Collections.Generic; | |
namespace AndroidTextDraw | |
{ | |
public static class AndroidDrawExtension | |
{ | |
private static Dictionary<uint, Texture2D> TextureCache = new Dictionary<uint, Texture2D>(); | |
// MS-PL from Monogame | |
private static void ConvertToABGR(int pixelHeight, int pixelWidth, int[] pixels) | |
{ | |
int pixelCount = pixelWidth * pixelHeight; | |
for (int i = 0; i < pixelCount; ++i) | |
{ | |
uint pixel = (uint)pixels[i]; | |
pixels[i] = (int)((pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16)); | |
} | |
} | |
public static void ClearCache(this SpriteBatch sb) | |
{ | |
foreach (var item in TextureCache) | |
{ | |
item.Value.Dispose(); | |
} | |
TextureCache.Clear(); | |
} | |
public static void ClearCache() | |
{ | |
foreach (var item in TextureCache) | |
{ | |
item.Value.Dispose(); | |
} | |
TextureCache.Clear(); | |
} | |
public static void DrawText(this SpriteBatch sb, int fontSize, string Text, Vector2 Position, Microsoft.Xna.Framework.Color color, Microsoft.Xna.Framework.Color bcolor) | |
{ | |
uint hash = (uint)(Text.GetHashCode() ^ bcolor.GetHashCode()); | |
if(TextureCache.ContainsKey(hash)) | |
{ | |
sb.Draw(TextureCache[hash], Position, color); | |
return; | |
} | |
Paint paint = new Paint(); | |
paint.SetTypeface(Typeface.Default); | |
paint.TextSize = fontSize; | |
Paint.FontMetrics fm = paint.GetFontMetrics(); | |
paint.Color = new Android.Graphics.Color(255, 255, 255, 255); | |
int height = (int)System.Math.Ceiling(fm.Descent - fm.Ascent); | |
int width = (int)System.Math.Ceiling(paint.MeasureText(Text)); | |
Bitmap bmp = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); | |
Canvas canvas = new Canvas(bmp); | |
canvas.DrawColor(new Android.Graphics.Color(bcolor.R, bcolor.G, bcolor.B, bcolor.A)); | |
canvas.DrawText(Text.ToCharArray(), 0, Text.Length, 0, -fm.Ascent, paint); | |
Texture2D t = new Texture2D(sb.GraphicsDevice, width, height, false, SurfaceFormat.Color); | |
int[] pix = new int[bmp.ByteCount / 4]; | |
bmp.GetPixels(pix, 0, bmp.Width, 0, 0, bmp.Width, bmp.Height); | |
ConvertToABGR(height, width, pix); | |
t.SetData<int>(pix); | |
bmp.Recycle(); | |
sb.Draw(t, Position, color); | |
TextureCache.Add(hash, t); | |
} | |
public static Texture2D GetDrawText(this SpriteBatch sb, int fontSize, string Text, Microsoft.Xna.Framework.Color color, Microsoft.Xna.Framework.Color bcolor) | |
{ | |
Paint paint = new Paint(); | |
paint.SetTypeface(Typeface.Default); | |
paint.TextSize = fontSize; | |
Paint.FontMetrics fm = paint.GetFontMetrics(); | |
paint.Color = new Android.Graphics.Color(255, 255, 255, 255); | |
int height = (int)System.Math.Ceiling(fm.Descent - fm.Ascent); | |
int width = (int)System.Math.Ceiling(paint.MeasureText(Text)); | |
Bitmap bmp = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); | |
Canvas canvas = new Canvas(bmp); | |
canvas.DrawColor(new Android.Graphics.Color(bcolor.R, bcolor.G, bcolor.B, bcolor.A)); | |
canvas.DrawText(Text.ToCharArray(), 0, Text.Length, 0, -fm.Ascent, paint); | |
Texture2D t = new Texture2D(sb.GraphicsDevice, width, height, false, SurfaceFormat.Color); | |
int[] pix = new int[bmp.ByteCount / 4]; | |
bmp.GetPixels(pix, 0, bmp.Width, 0, 0, bmp.Width, bmp.Height); | |
ConvertToABGR(height, width, pix); | |
t.SetData<int>(pix); | |
bmp.Recycle(); | |
return t; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment