1 module polyplex.core.render.simplefont;
2 import polyplex.utils.random;
3 import polyplex.core;
4 import polyplex.math;
5 import polyplex.core.render.gl.shader;
6 import std.stdio;
7 
8 public class SpriteFontSimple {
9 	private Texture2D font_texture;
10 	private SpriteBatch sprite_batch;
11 	private ContentManager manager;
12 	private Vector2i font_split;
13 	private static Random rng;
14 
15 	this(SpriteBatch batcher, ContentManager man, string font_name, Vector2i font_split = Vector2i(10, 10)) {
16 		this.sprite_batch = batcher;
17 		this.manager = man;
18 		this.font_texture = manager.Load!Texture2D(font_name);
19 		this.font_split = font_split;
20 		if (rng is null) rng = new Random();
21 	}
22 
23 	this(ContentManager man, string font_name, Vector2i font_split = Vector2i(10, 10)) {
24 		this.manager = man;
25 		this.font_texture = manager.Load!Texture2D(font_name);
26 		this.font_split = font_split;
27 		if (rng is null) rng = new Random();
28 	}
29 
30 	private Vector2 get_glyph(char chr) {
31 		float chr_f = cast(float)chr-33;
32 		return Vector2(chr_f%font_split.X, (chr_f/font_split.Y)%font_split.Y);
33 	}
34 
35 	public Vector2 MeasureString(string text, float scale = 1f) {
36 		Vector2 cursor_pos = Vector2(0, ((font_texture.Height/font_split.Y) - 2f)*scale);
37 		foreach(char c; text) {
38 			Vector2 glyph_pos = get_glyph(c);
39 			cursor_pos += Vector2(((font_texture.Width/font_split.X) - 2f)*scale, 0f);
40 			if (c == '\n') {
41 				cursor_pos += Vector2(0f, ((font_texture.Height/font_split.Y) - 2f)*scale);
42 			}
43 		}
44 		return cursor_pos;
45 	}
46 
47 	public void DrawString(string text, Vector2 position, float scale = 1f, Color color = Color.White, GameTimes game_time = null, bool shake = false, float intensity = 1f) {
48 		DrawString(sprite_batch, text, position, scale, color, game_time, shake, intensity);
49 	}
50 
51 	public void DrawString(SpriteBatch sprite_batch, string text, Vector2 position, float scale = 1f, Color color = Color.White, GameTimes game_time = null, bool shake = false, float intensity = 1f) {
52 		Vector2 cursor_pos = position;
53 		foreach(char c; text) {
54 			Vector2 shake_offset = Vector2(0, 0);
55 			if (shake) {
56 				shake_offset = Vector2(Mathf.Sin(game_time.TotalTime.Seconds+cursor_pos.X+rng.Next())*intensity, Mathf.Cos(game_time.TotalTime.Seconds+cursor_pos.Y+rng.Next())*intensity);
57 			}
58 			Vector2 glyph_pos = get_glyph(c);
59 			if (c != ' ' && c != '\n')
60 			sprite_batch.Draw(
61 				font_texture, 
62 				new Rectangle(
63 					cast(int)(cursor_pos.X+shake_offset.X), 
64 					cast(int)(cursor_pos.Y+shake_offset.Y), 
65 					cast(int)((font_texture.Width/font_split.X)*scale), 
66 					cast(int)((font_texture.Height/font_split.Y)*scale)),
67 				new Rectangle(
68 					cast(int)glyph_pos.X*(font_texture.Width/font_split.X), 
69 					cast(int)glyph_pos.Y*(font_texture.Height/font_split.Y), 
70 					(font_texture.Width/font_split.X)/2, 
71 					(font_texture.Height/font_split.Y)/2),
72 				color);
73 			cursor_pos += Vector2(((font_texture.Width/font_split.X) - 2f)*scale, 0f);
74 			if (c == '\n') {
75 				cursor_pos += Vector2(0f, ((font_texture.Height/font_split.Y) - 2f)*scale);
76 				cursor_pos = Vector2(position.X, cursor_pos.Y);
77 			}
78 		}
79 	}
80 }