private void DrawPreview() { Size size; string text; text = previewTextBox.Text; size = _font.MeasureFont(text); if (size.Height != 0 && size.Width != 0) { Bitmap image; int x; int y; char previousCharacter; image = new Bitmap(size.Width, size.Height); x = 0; y = 0; previousCharacter = ' '; using (Graphics g = Graphics.FromImage(image)) { foreach (char character in text) { switch (character) { case '\n': x = 0; y += _font.LineHeight; break; case '\r': break; default: Character data; int kerning; data = _font[character]; kerning = _font.GetKerning(previousCharacter, character); this.DrawCharacter(g, data, x + data.Offset.X + kerning, y + data.Offset.Y); x += data.XAdvance + kerning; break; } previousCharacter = character; } } previewImageBox.Image = image; } }
public override void DrawTexture() { Positions.Clear(); Colors.Clear(); TextureCoordinates.Clear(); // http://www.cyotek.com/blog/angelcode-bitmap-font-parsing-using-csharp foreach (var textInfo in TextInfo) { textInfo.Offsets.Clear(); int x = 0; int y = 0; var w = bmpFont.TextureSize.Width; var h = bmpFont.TextureSize.Height; char previousCharacter; previousCharacter = ' '; var normalizedText = textInfo.Text; foreach (char character in normalizedText) { switch (character) { case '\n': x = 0; y -= bmpFont.LineHeight; break; default: Character data = bmpFont[character]; int kerning = bmpFont.GetKerning(previousCharacter, character); //DrawCharacter(data, x + data.Offset.X + kerning, y + data.Offset.Y, builder); DrawCharacter(data, new Vector3(x, y, 0), w, h, kerning, textInfo); x += data.XAdvance + kerning; break; } previousCharacter = character; } } UpdateBounds(); }
protected override void OnDrawTexture(IDeviceResources deviceResources) { Texture = TextureStatic; Width = 0; Height = 0; // http://www.cyotek.com/blog/angelcode-bitmap-font-parsing-using-csharp var tempList = new List <BillboardVertex>(100); foreach (var textInfo in TextInfo) { tempList.Clear(); int x = 0; int y = 0; var w = BitmapFont.TextureSize.Width; var h = BitmapFont.TextureSize.Height; char previousCharacter; previousCharacter = ' '; var normalizedText = textInfo.Text; var rect = new RectangleF(textInfo.Origin.X, textInfo.Origin.Y, 0, 0); foreach (char character in normalizedText) { switch (character) { case '\n': x = 0; y -= BitmapFont.LineHeight; break; default: Character data = BitmapFont[character]; int kerning = BitmapFont.GetKerning(previousCharacter, character); tempList.Add(DrawCharacter(data, new Vector3(x + data.Offset.X, y - data.Offset.Y, 0), w, h, kerning, textInfo)); x += data.XAdvance + kerning; break; } previousCharacter = character; if (tempList.Count > 0) { rect.Width = Math.Max(rect.Width, x * textInfo.Scale * textureScale); rect.Height = Math.Max(rect.Height, Math.Abs(tempList.Last().OffBR.Y)); } } var halfW = rect.Width / 2; var halfH = rect.Height / 2; BillboardVertices.Add(new BillboardVertex() { Position = textInfo.Origin.ToVector4(), Background = textInfo.Background, TexTL = Vector2.Zero, TexBR = Vector2.Zero, OffTL = new Vector2(-halfW, halfH), OffBR = new Vector2(halfW, -halfH), }); textInfo.UpdateTextInfo(rect.Width, rect.Height); foreach (var vert in tempList) { var v = vert; v.OffTL += new Vector2(-halfW, halfH); v.OffBR += new Vector2(-halfW, halfH); BillboardVertices.Add(v); } Width += rect.Width; Height += rect.Height; } }
private Mesh GenerateLineMesh(Vector3 position, string str, Vector3 renderSize) { Font.Color = new Color(255, 255, 255, 70); //Set up mesh structures List <int> Triangles = new List <int>(); List <Vector3> vertices = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); //Keep track of position Vector3 curPos = position; Vector3 scale = renderSize / Font.Size; scale.x = 1; scale.y = 1; scale.z = 1; for (int idx = 0; idx < str.Length; idx++) { char c = str[idx]; BitmapChar charInfo = Font.GetBitmapChar((int)c); int vertIndex = vertices.Count; //Set up uvs Rect uvRect = Font.GetUVRect(charInfo); //Debug.Log(uvRect); Vector2 uvScale = new Vector2(uvRect.width, uvRect.height); Vector2 uvOffset = new Vector2(uvRect.x, uvRect.y); for (int i = 0; i < quadUvs.Length; i++) { uvs.Add(Vector2.Scale(quadUvs[i], uvScale) + uvOffset); } //Set up verts Vector3 vertSize = Vector2.Scale(charInfo.Size, scale); Vector3 vertOffset = Vector2.Scale(charInfo.Offset, scale); vertOffset.y = renderSize.y - (vertOffset.y + vertSize.y); // change offset from top to bottom for (int i = 0; i < quadVerts.Length; i++) { Vector3 vert = Vector3.Scale(quadVerts[i], vertSize) + curPos + vertOffset; vert.x = (int)vert.x; vert.y = (int)vert.y; vert.z = (int)vert.z; //Debug.Log(vert); vertices.Add(vert); } //Set up triangles for (int i = 0; i < quadTriangles.Length; i++) { Triangles.Add(quadTriangles[i] + vertIndex); } //Advance cursor float krn = 0; if (idx < Text.Length - 1) { krn = Font.GetKerning(c, Text[idx + 1]); } curPos.x += (charInfo.XAdvance + krn) * scale.x * spacing; } //Assign verts, uvs, tris and materials to mesh Mesh mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.uv = uvs.ToArray(); mesh.subMeshCount = 1; mesh.SetTriangles(Triangles.ToArray(), 0); return(mesh); }
protected override void OnUpdateTextureAndBillboardVertices(IDeviceResources deviceResources) { Width = 0; Height = 0; // http://www.cyotek.com/blog/angelcode-bitmap-font-parsing-using-csharp var tempList = new List <BillboardVertex>(100); foreach (var textInfo in TextInfo) { int tempPrevCount = tempList.Count; int x = 0; int y = 0; var w = BitmapFont.TextureSize.Width; var h = BitmapFont.TextureSize.Height; char previousCharacter; previousCharacter = ' '; var normalizedText = textInfo.Text; var rect = new RectangleF(textInfo.Origin.X, textInfo.Origin.Y, 0, 0); foreach (char character in normalizedText) { switch (character) { case '\n': x = 0; y -= BitmapFont.LineHeight; break; default: Character data = BitmapFont[character]; int kerning = BitmapFont.GetKerning(previousCharacter, character); tempList.Add(DrawCharacter(data, new Vector3(x + data.Offset.X, y - data.Offset.Y, 0), w, h, kerning, textInfo)); x += data.XAdvance + kerning; break; } previousCharacter = character; if (tempList.Count > 0) { rect.Width = Math.Max(rect.Width, x * textInfo.Scale * textureScale); rect.Height = Math.Max(rect.Height, Math.Abs(tempList.Last().OffBR.Y)); } } var transform = textInfo.Angle != 0 ? Matrix3x2.Rotation(textInfo.Angle) : Matrix3x2.Identity; var halfW = rect.Width / 2; var halfH = rect.Height / 2; //Add backbround vertex first. This also used for hit test BillboardVertices.Add(new BillboardVertex() { Position = textInfo.Origin.ToVector4(), Background = textInfo.Background, TexTL = Vector2.Zero, TexBR = Vector2.Zero, OffTL = Matrix3x2.TransformPoint(transform, new Vector2(-halfW, halfH)), OffBR = Matrix3x2.TransformPoint(transform, new Vector2(halfW, -halfH)), OffTR = Matrix3x2.TransformPoint(transform, new Vector2(-halfW, -halfH)), OffBL = Matrix3x2.TransformPoint(transform, new Vector2(halfW, halfH)), }); textInfo.UpdateTextInfo(rect.Width, rect.Height); for (int k = tempPrevCount; k < tempList.Count; ++k) { var v = tempList[k]; v.OffTL = Matrix3x2.TransformPoint(transform, v.OffTL + new Vector2(-halfW, halfH)); v.OffBR = Matrix3x2.TransformPoint(transform, v.OffBR + new Vector2(-halfW, halfH)); v.OffTR = Matrix3x2.TransformPoint(transform, v.OffTR + new Vector2(-halfW, halfH)); v.OffBL = Matrix3x2.TransformPoint(transform, v.OffBL + new Vector2(-halfW, halfH)); tempList[k] = v; } Width += rect.Width; Height += rect.Height; } foreach (var v in tempList) { BillboardVertices.Add(v); } }
public int GetKerning(BitmapFont font, ISymbol previousData) => previousData.SymbolType == SymbolType.Icon ? 0 : font.GetKerning(previousData.Character, Character);