BMFont.GetGlyph C# (CSharp) Method

GetGlyph() public method

Retrieve the specified glyph, if it's present.
public GetGlyph ( int index ) : BMGlyph,
index int
return BMGlyph,
	public BMGlyph GetGlyph (int index) { return GetGlyph(index, false); }

Same methods

BMFont::GetGlyph ( int index, bool createIfMissing ) : BMGlyph,

Usage Example

Ejemplo n.º 1
0
	/// <summary>
	/// Create a bitmap font from the specified dynamic font.
	/// </summary>

	static public bool CreateFont (Font ttf, int size, int faceIndex, bool kerning, string characters, int padding, out BMFont font, out Texture2D tex)
	{
		font = null;
		tex = null;

		if (ttf == null || !isPresent) return false;

		IntPtr lib = IntPtr.Zero;
		IntPtr face = IntPtr.Zero;

		if (FT_Init_FreeType(out lib) != 0)
		{
			Debug.LogError("Failed to initialize FreeType");
			return false;
		}

		string fileName = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".Length) +
			UnityEditor.AssetDatabase.GetAssetPath(ttf);

		if (!File.Exists(fileName))
		{
			Debug.LogError("Unable to use the chosen font.");
		}
		else if (FT_New_Face(lib, fileName, faceIndex, out face) != 0)
		{
			Debug.LogError("Unable to use the chosen font (FT_New_Face).");
		}
		else
		{
			font = new BMFont();
			font.charSize = size;

			Color32 white = Color.white;
			List<int> entries = new List<int>();
			List<Texture2D> textures = new List<Texture2D>();

			FT_FaceRec faceRec = (FT_FaceRec)Marshal.PtrToStructure(face, typeof(FT_FaceRec));
			FT_Set_Pixel_Sizes(face, 0, (uint)size);

			// Calculate the baseline value that would let the printed font be centered vertically
			//int ascender = (faceRec.met.ascender >> 6);
			//int descender = (faceRec.descender >> 6);
			//int baseline = ((ascender - descender) >> 1);
			//if ((baseline & 1) == 1) --baseline;

			//Debug.Log(ascender + " " + descender + " " + baseline);

			// Space character is not renderable
			FT_Load_Glyph(face, FT_Get_Char_Index(face, 32), FT_LOAD_DEFAULT);
			FT_GlyphSlotRec space = (FT_GlyphSlotRec)Marshal.PtrToStructure(faceRec.glyph, typeof(FT_GlyphSlotRec));

			// Space is not visible and doesn't have a texture
			BMGlyph spaceGlyph = font.GetGlyph(32, true);
			spaceGlyph.offsetX = 0;
			spaceGlyph.offsetY = 0;
			spaceGlyph.advance = (space.metrics.horiAdvance >> 6);
			spaceGlyph.channel = 15;
			spaceGlyph.x = 0;
			spaceGlyph.y = 0;
			spaceGlyph.width = 0;
			spaceGlyph.height = 0;

			// Save kerning information
			if (kerning)
			{
				for (int b = 0; b < characters.Length; ++b)
				{
					uint ch2 = characters[b];
					if (ch2 == 32) continue;

					FT_Vector vec;
					if (FT_Get_Kerning(face, ch2, 32, 0, out vec) != 0) continue;

					int offset = (vec.x >> 6);
					if (offset != 0) spaceGlyph.SetKerning((int)ch2, offset);
				}
			}

			// Run through all requested characters
			foreach (char ch in characters)
			{
				uint charIndex = FT_Get_Char_Index(face, (uint)ch);
				FT_Load_Glyph(face, charIndex, FT_LOAD_DEFAULT);
				FT_GlyphSlotRec glyph = (FT_GlyphSlotRec)Marshal.PtrToStructure(faceRec.glyph, typeof(FT_GlyphSlotRec));
				FT_Render_Glyph(ref glyph, FT_Render_Mode.FT_RENDER_MODE_NORMAL);

				if (glyph.bitmap.width > 0 && glyph.bitmap.rows > 0)
				{
					byte[] buffer = new byte[glyph.bitmap.width * glyph.bitmap.rows];
					Marshal.Copy(glyph.bitmap.buffer, buffer, 0, buffer.Length);

					Texture2D texture = new Texture2D(glyph.bitmap.width, glyph.bitmap.rows, UnityEngine.TextureFormat.ARGB32, false);
					Color32[] colors = new Color32[buffer.Length];

					for (int i = 0, y = 0; y < glyph.bitmap.rows; ++y)
					{
						for (int x = 0; x < glyph.bitmap.width; ++x)
						{
							white.a = buffer[i++];
							colors[x + glyph.bitmap.width * (glyph.bitmap.rows - y - 1)] = white;
						}
					}

					// Save the texture
					texture.SetPixels32(colors);
					texture.Apply();
					textures.Add(texture);
					entries.Add(ch);

					// Record the metrics
					BMGlyph bmg = font.GetGlyph(ch, true);
					bmg.offsetX = (glyph.metrics.horiBearingX >> 6);
					bmg.offsetY = -(glyph.metrics.horiBearingY >> 6);
					bmg.advance = (glyph.metrics.horiAdvance >> 6);
					bmg.channel = 15;

					// Save kerning information
					if (kerning)
					{
						for (int b = 0; b < characters.Length; ++b)
						{
							uint ch2 = characters[b];
							if (ch2 == ch) continue;

							FT_Vector vec;
							if (FT_Get_Kerning(face, ch2, ch, 0, out vec) != 0) continue;

							int offset = (vec.x >> 6);
							if (offset != 0) bmg.SetKerning((int)ch2, offset);
						}
					}
				}
			}

			// Create a packed texture with all the characters
			tex = new Texture2D(32, 32, TextureFormat.ARGB32, false);
			Rect[] rects = tex.PackTextures(textures.ToArray(), padding);

			// Make the RGB channel pure white
			Color32[] cols = tex.GetPixels32();
			for (int i = 0, imax = cols.Length; i < imax; ++i)
			{
				Color32 c = cols[i];
				c.r = 255;
				c.g = 255;
				c.b = 255;
				cols[i] = c;
			}
			tex.SetPixels32(cols);
			tex.Apply();

			font.texWidth = tex.width;
			font.texHeight = tex.height;

			int min = int.MaxValue;
			int max = int.MinValue;

			// Other glyphs are visible and need to be added
			for (int i = 0, imax = entries.Count; i < imax; ++i)
			{
				// Destroy the texture now that it's a part of an atlas
				UnityEngine.Object.DestroyImmediate(textures[i]);
				textures[i] = null;
				Rect rect = rects[i];

				// Set the texture coordinates
				BMGlyph glyph = font.GetGlyph(entries[i], true);
				glyph.x = Mathf.RoundToInt(rect.x * font.texWidth);
				glyph.y = Mathf.RoundToInt(rect.y * font.texHeight);
				glyph.width = Mathf.RoundToInt(rect.width * font.texWidth);
				glyph.height = Mathf.RoundToInt(rect.height * font.texHeight);

				// Flip the Y since the UV coordinate system is different
				glyph.y = font.texHeight - glyph.y - glyph.height;

				max = Mathf.Max(max, -glyph.offsetY);
				min = Mathf.Min(min, -glyph.offsetY - glyph.height);
			}

			int baseline = size + min;
			baseline += ((max - min - size) >> 1);

			// Offset all glyphs so that they are not using the baseline
			for (int i = 0, imax = entries.Count; i < imax; ++i)
			{
				BMGlyph glyph = font.GetGlyph(entries[i], true);
				glyph.offsetY += baseline;
			}
		}
		
		if (face != IntPtr.Zero) FT_Done_Face(face);
#if !UNITY_3_5
		if (lib != IntPtr.Zero) FT_Done_FreeType(lib);
#endif
		return (tex != null);
	}
All Usage Examples Of BMFont::GetGlyph