GetGlyph() public method

Retrieve the specified glyph, if it's present.
public GetGlyph ( int index ) : BMGlyph,
index int
return BMGlyph,
示例#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);
	}
示例#2
0
    /// <summary>
    /// Reload the font data.
    /// </summary>
    public static void Load(BMFont font, string name, byte[] bytes)
    {
        font.Clear();

        if (bytes != null)
        {
            int offset = 0;
            char[] separator = new char[1] { ' ' };

            while (offset < bytes.Length)
            {
                string line = ReadLine(bytes, ref offset);
                if (string.IsNullOrEmpty(line)) break;
                string[] split = line.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);

                if (split[0] == "char")
                {
                    // Expected data style:
                    // char id=13 x=506 y=62 width=3 height=3 xoffset=-1 yoffset=50 xadvance=0 page=0 chnl=15

                    if (split.Length > 8)
                    {
                        int id = GetInt(split[1]);
                        BMGlyph glyph = font.GetGlyph(id, true);

                        if (glyph != null)
                        {
                            glyph.x			= GetInt(split[2]);
                            glyph.y			= GetInt(split[3]);
                            glyph.width		= GetInt(split[4]);
                            glyph.height	= GetInt(split[5]);
                            glyph.offsetX	= GetInt(split[6]);
                            glyph.offsetY	= GetInt(split[7]);
                            glyph.advance	= GetInt(split[8]);
                        }
                        else Debug.Log("Char: " + split[1] + " (" + id + ") is NULL");
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'char' field (" +
                            name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "kerning")
                {
                    // Expected data style:
                    // kerning first=84 second=244 amount=-5

                    if (split.Length > 3)
                    {
                        int first  = GetInt(split[1]);
                        int second = GetInt(split[2]);
                        int amount = GetInt(split[3]);

                        BMGlyph glyph = font.GetGlyph(second, true);
                        if (glyph != null) glyph.SetKerning(first, amount);
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'kerning' field (" +
                            name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "common")
                {
                    // Expected data style:
                    // common lineHeight=64 base=51 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=1 redChnl=4 greenChnl=4 blueChnl=4

                    if (split.Length > 5)
                    {
                        font.charSize	= GetInt(split[1]);
                        font.baseOffset = GetInt(split[2]);
                        font.texWidth	= GetInt(split[3]);
                        font.texHeight	= GetInt(split[4]);

                        int pages = GetInt(split[5]);

                        if (pages != 1)
                        {
                            Debug.LogError("Font '" + name + "' must be created with only 1 texture, not " + pages);
                            break;
                        }
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'common' field (" +
                            name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "page")
                {
                    // Expected data style:
                    // page id=0 file="textureName.png"

                    if (split.Length > 2)
                    {
                        font.spriteName = GetString(split[2]).Replace("\"", "");
                    }
                }
            }
        }
    }
示例#3
0
    /// <summary>
    /// Reload the font data.
    /// </summary>
    public static void Load(BMFont font, string name, byte[] bytes)
    {
        font.Clear();

        if (bytes != null)
        {
            BmByteReader reader = new BmByteReader(bytes);
            char[] separator = new char[] { ' ' };

            while (reader.canRead)
            {
                string line = reader.ReadLine();
                if (string.IsNullOrEmpty(line)) break;
                string[] split = line.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);
                int len = split.Length;

                if (split[0] == "char")
                {
                    // Expected data style:
                    // char id=13 x=506 y=62 width=3 height=3 xoffset=-1 yoffset=50 xadvance=0 page=0 chnl=15

                    int channel = (len > 10) ? GetInt(split[10]) : 15;

                    if (len > 9 && GetInt(split[9]) > 0)
                    {
                        Debug.LogError("Your font was exported with more than one texture. Only one texture is supported by NGUI.\n" +
                            "You need to re-export your font, enlarging the texture's dimensions until everything fits into just one texture.");
                        break;
                    }

                    if (len > 8)
                    {
                        int id = GetInt(split[1]);
                        BMGlyph glyph = font.GetGlyph(id, true);

                        if (glyph != null)
                        {
                            glyph.x			= GetInt(split[2]);
                            glyph.y			= GetInt(split[3]);
                            glyph.width		= GetInt(split[4]);
                            glyph.height	= GetInt(split[5]);
                            glyph.offsetX	= GetInt(split[6]);
                            glyph.offsetY	= GetInt(split[7]);
                            glyph.advance	= GetInt(split[8]);
                            glyph.channel	= channel;
                        }
                        else Debug.Log("Char: " + split[1] + " (" + id + ") is NULL");
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'char' field (" + name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "kerning")
                {
                    // Expected data style:
                    // kerning first=84 second=244 amount=-5

                    if (len > 3)
                    {
                        int first  = GetInt(split[1]);
                        int second = GetInt(split[2]);
                        int amount = GetInt(split[3]);

                        BMGlyph glyph = font.GetGlyph(second, true);
                        if (glyph != null) glyph.SetKerning(first, amount);
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'kerning' field (" +
                            name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "common")
                {
                    // Expected data style:
                    // common lineHeight=64 base=51 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=1 redChnl=4 greenChnl=4 blueChnl=4

                    if (len > 5)
                    {
                        font.charSize	= GetInt(split[1]);
                        font.baseOffset = GetInt(split[2]);
                        font.texWidth	= GetInt(split[3]);
                        font.texHeight	= GetInt(split[4]);

                        int pages = GetInt(split[5]);

                        if (pages != 1)
                        {
                            Debug.LogError("Font '" + name + "' must be created with only 1 texture, not " + pages);
                            break;
                        }
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'common' field (" +
                            name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "page")
                {
                    // Expected data style:
                    // page id=0 file="textureName.png"

                    if (len > 2)
                    {
                        font.spriteName = GetString(split[2]).Replace("\"", "");
                        font.spriteName = font.spriteName.Replace(".png", "");
                        font.spriteName = font.spriteName.Replace(".tga", "");
                    }
                }
            }
        }
    }
示例#4
0
    /// <summary>
    /// Get the printed size of the specified string. The returned value is in local coordinates. Multiply by transform's scale to get pixels.
    /// </summary>

    public Vector2 CalculatePrintedSize(string text, bool encoding, SymbolStyle symbolStyle)
    {
        if (mReplacement != null)
        {
            return(mReplacement.CalculatePrintedSize(text, encoding, symbolStyle));
        }

        Vector2 v = Vector2.zero;

        if (UseDynamicFont || (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)))
        {
            if (encoding)
            {
                text = NGUITools.StripSymbols(text);
            }

            if (UseDynamicFont)
            {
                dynamicFont.RequestCharactersInTexture(text, dynamicFontSize, dynamicFontStyle);
            }
            CharacterInfo charInfo;

            int length     = text.Length;
            int maxX       = 0;
            int x          = 0;
            int y          = 0;
            int prev       = 0;
            int lineHeight = (charSize + mSpacingY);

            for (int i = 0; i < length; ++i)
            {
                char c = text[i];

                // Start a new line
                if (c == '\n')
                {
                    if (x > maxX)
                    {
                        maxX = x;
                    }
                    x    = 0;
                    y   += lineHeight;
                    prev = 0;
                    continue;
                }

                // Skip invalid characters
                if (c < ' ')
                {
                    prev = 0; continue;
                }


                if (UseDynamicFont)
                {
                    if (dynamicFont.GetCharacterInfo(c, out charInfo, dynamicFontSize, dynamicFontStyle))
                    {
                        x += (int)(mSpacingX + charInfo.width);
                    }
                    else
                    {
                    }
                }
                else
                {
                    // See if there is a symbol matching this text
                    BMSymbol symbol = (encoding && symbolStyle != SymbolStyle.None) ? mFont.MatchSymbol(text, i, length) : null;

                    if (symbol == null)
                    {
                        // Get the glyph for this character
                        BMGlyph glyph = mFont.GetGlyph(c);

                        if (glyph != null)
                        {
                            x   += mSpacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance);
                            prev = c;
                        }
                    }
                    else
                    {
                        // Symbol found -- use it
                        x   += mSpacingX + symbol.width;
                        i   += symbol.length - 1;
                        prev = 0;
                    }
                }
            }

            // Convert from pixel coordinates to local coordinates
            float scale = (charSize > 0) ? 1f / charSize : 1f;
            v.x = scale * ((x > maxX) ? x : maxX);
            v.y = scale * (y + lineHeight);
        }
        return(v);
    }
示例#5
0
    /// <summary>
    /// Reload the font data.
    /// </summary>

    public static void Load(BMFont font, string name, byte[] bytes)
    {
        font.Clear();

        if (bytes != null)
        {
            ByteReader reader    = new ByteReader(bytes);
            char[]     separator = new char[] { ' ' };

            while (reader.canRead)
            {
                string line = reader.ReadLine();
                if (string.IsNullOrEmpty(line))
                {
                    break;
                }
                string[] split = line.Split(separator, System.StringSplitOptions.RemoveEmptyEntries);
                int      len   = split.Length;

                if (split[0] == "char")
                {
                    // Expected data style:
                    // char id=13 x=506 y=62 width=3 height=3 xoffset=-1 yoffset=50 xadvance=0 page=0 chnl=15

                    int channel = (len > 10) ? GetInt(split[10]) : 15;

                    if (len > 9 && GetInt(split[9]) > 0)
                    {
                        Debug.LogError("Your font was exported with more than one texture. Only one texture is supported by NGUI.\n" +
                                       "You need to re-export your font, enlarging the texture's dimensions until everything fits into just one texture.");
                        break;
                    }

                    if (len > 8)
                    {
                        int     id    = GetInt(split[1]);
                        BMGlyph glyph = font.GetGlyph(id, true);

                        if (glyph != null)
                        {
                            glyph.x       = GetInt(split[2]);
                            glyph.y       = GetInt(split[3]);
                            glyph.width   = GetInt(split[4]);
                            glyph.height  = GetInt(split[5]);
                            glyph.offsetX = GetInt(split[6]);
                            glyph.offsetY = GetInt(split[7]);
                            glyph.advance = GetInt(split[8]);
                            glyph.channel = channel;
                        }
                        else
                        {
                            Debug.Log("Char: " + split[1] + " (" + id + ") is NULL");
                        }
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'char' field (" + name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "kerning")
                {
                    // Expected data style:
                    // kerning first=84 second=244 amount=-5

                    if (len > 3)
                    {
                        int first  = GetInt(split[1]);
                        int second = GetInt(split[2]);
                        int amount = GetInt(split[3]);

                        BMGlyph glyph = font.GetGlyph(second, true);
                        if (glyph != null)
                        {
                            glyph.SetKerning(first, amount);
                        }
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'kerning' field (" +
                                       name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "common")
                {
                    // Expected data style:
                    // common lineHeight=64 base=51 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=1 redChnl=4 greenChnl=4 blueChnl=4

                    if (len > 5)
                    {
                        font.charSize   = GetInt(split[1]);
                        font.baseOffset = GetInt(split[2]);
                        font.texWidth   = GetInt(split[3]);
                        font.texHeight  = GetInt(split[4]);

                        int pages = GetInt(split[5]);

                        if (pages != 1)
                        {
                            Debug.LogError("Font '" + name + "' must be created with only 1 texture, not " + pages);
                            break;
                        }
                    }
                    else
                    {
                        Debug.LogError("Unexpected number of entries for the 'common' field (" +
                                       name + ", " + split.Length + "):\n" + line);
                        break;
                    }
                }
                else if (split[0] == "page")
                {
                    // Expected data style:
                    // page id=0 file="textureName.png"

                    if (len > 2)
                    {
                        font.spriteName = GetString(split[2]).Replace("\"", "");
                        font.spriteName = font.spriteName.Replace(".png", "");
                        font.spriteName = font.spriteName.Replace(".tga", "");
                    }
                }
            }
        }
    }
示例#6
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, 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(), 1);

            // 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);
    }
示例#7
0
    /// <summary>
    /// Get the printed size of the specified string. The returned value is in pixels.
    /// </summary>
    ///change by chenzhiwei return value v.z is line count
    public Vector3 CalculatePrintedSize(string text, int size, bool encoding, SymbolStyle symbolStyle)
    {
        if (mReplacement != null)
        {
            return(mReplacement.CalculatePrintedSize(text, size, encoding, symbolStyle));
        }

#if DYNAMIC_FONT
        if (isDynamic)
        {
            return(NGUIText.CalculatePrintedSize(text, mDynamicFont, size, mDynamicFontStyle, encoding));
        }
#endif
        Vector3 v = Vector3.zero;

        if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text))
        {
            if (encoding)
            {
                text = NGUIText.StripSymbols(text);
            }

            int  length     = text.Length;
            int  maxX       = 0;
            int  x          = 0;
            int  y          = 0;
            int  prev       = 0;
            int  fs         = size;
            int  lineHeight = (fs + mSpacingY);
            bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols;

            for (int i = 0; i < length; ++i)
            {
                char c = text[i];

                // Start a new line
                if (c == '\n')
                {
                    if (x > maxX)
                    {
                        maxX = x;
                    }
                    x  = 0;
                    y += lineHeight;
                    v.z++;
                    prev = 0;
                    continue;
                }

                // Skip invalid characters
                if (c < ' ')
                {
                    prev = 0; continue;
                }

                // See if there is a symbol matching this text
                BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null;

                if (symbol == null)
                {
                    // Get the glyph for this character
                    BMGlyph glyph = mFont.GetGlyph(c);

                    if (glyph != null)
                    {
                        x   += mSpacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance);
                        prev = c;
                    }
                }
                else
                {
                    // Symbol found -- use it
                    x   += mSpacingX + symbol.width;
                    i   += symbol.length - 1;
                    prev = 0;
                }
            }

            // Convert from pixel coordinates to local coordinates
            v.x = ((x > maxX) ? x : maxX);
            v.y = (y + lineHeight);
            v.z++;
        }
        return(v);
    }
示例#8
0
    /// <summary>
    /// Get the printed size of the specified string. The returned value is in pixels.
    /// </summary>

    public Vector2 CalculatePrintedSize(string text)
    {
        if (mReplacement != null)
        {
            return(mReplacement.CalculatePrintedSize(text));
        }

#if DYNAMIC_FONT
        if (isDynamic)
        {
            NGUIText.current.size  = mDynamicFontSize;
            NGUIText.current.style = mDynamicFontStyle;
            return(NGUIText.CalculatePrintedSize(mDynamicFont, text));
        }
#endif
        Vector2 v = Vector2.zero;

        if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text))
        {
            if (NGUIText.current.encoding)
            {
                text = NGUIText.StripSymbols(text);
            }

            int  x          = 0;
            int  y          = 0;
            int  prev       = 0;
            int  maxX       = 0;
            int  length     = text.Length;
            int  lineHeight = NGUIText.current.size + NGUIText.current.spacingY;
            bool useSymbols = NGUIText.current.encoding && NGUIText.current.symbolStyle != NGUIText.SymbolStyle.None && hasSymbols;

            for (int i = 0; i < length; ++i)
            {
                char c = text[i];

                // Start a new line
                if (c == '\n')
                {
                    if (x > maxX)
                    {
                        maxX = x;
                    }
                    x    = 0;
                    y   += lineHeight;
                    prev = 0;
                    continue;
                }

                // Skip invalid characters
                if (c < ' ')
                {
                    prev = 0; continue;
                }

                // See if there is a symbol matching this text
                BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null;

                if (symbol == null)
                {
                    // Get the glyph for this character
                    BMGlyph glyph = mFont.GetGlyph(c);

                    if (glyph != null)
                    {
                        x   += NGUIText.current.spacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance);
                        prev = c;
                    }
                }
                else
                {
                    // Symbol found -- use it
                    x   += NGUIText.current.spacingX + symbol.width;
                    i   += symbol.length - 1;
                    prev = 0;
                }
            }

            // Padding is always between characters, so it's one less than the number of characters
            v.x = ((x > maxX) ? x : maxX);
            v.y = (y + NGUIText.current.size);
        }
        return(v);
    }
示例#9
0
    /// <summary>
    /// Get the printed size of the specified string. The returned value is in local coordinates. Multiply by transform's scale to get pixels.
    /// </summary>

    public Vector2 CalculatePrintedSize(string text, bool encoding, SymbolStyle symbolStyle)
    {
        if (mReplacement != null)
        {
            return(mReplacement.CalculatePrintedSize(text, encoding, symbolStyle));
        }

        Vector2 v       = Vector2.zero;
        bool    dynamic = isDynamic;

#if DYNAMIC_FONT
        if (dynamic || (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)))
#else
        if (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text))
#endif
        {
            if (encoding)
            {
                text = NGUITools.StripSymbols(text);
            }
#if DYNAMIC_FONT
            if (dynamic)
            {
                mDynamicFont.textureRebuildCallback = OnFontChanged;
                mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize, mDynamicFontStyle);
                mDynamicFont.textureRebuildCallback = null;
            }
#endif
            int  length     = text.Length;
            int  maxX       = 0;
            int  x          = 0;
            int  y          = 0;
            int  prev       = 0;
            int  fs         = size;
            int  lineHeight = (fs + mSpacingY);
            bool useSymbols = encoding && symbolStyle != SymbolStyle.None && hasSymbols;

            for (int i = 0; i < length; ++i)
            {
                char c = text[i];

                // Start a new line
                if (c == '\n')
                {
                    if (x > maxX)
                    {
                        maxX = x;
                    }
                    x    = 0;
                    y   += lineHeight;
                    prev = 0;
                    continue;
                }

                // Skip invalid characters
                if (c < ' ')
                {
                    prev = 0; continue;
                }

                if (!dynamic)
                {
                    // See if there is a symbol matching this text
                    BMSymbol symbol = useSymbols ? MatchSymbol(text, i, length) : null;

                    if (symbol == null)
                    {
                        // Get the glyph for this character
                        BMGlyph glyph = mFont.GetGlyph(c);

                        if (glyph != null)
                        {
                            x   += mSpacingX + ((prev != 0) ? glyph.advance + glyph.GetKerning(prev) : glyph.advance);
                            prev = c;
                        }
                    }
                    else
                    {
                        // Symbol found -- use it
                        x   += mSpacingX + symbol.width;
                        i   += symbol.length - 1;
                        prev = 0;
                    }
                }
#if DYNAMIC_FONT
                else
                {
                    if (mDynamicFont.GetCharacterInfo(c, out mChar, mDynamicFontSize, mDynamicFontStyle))
                    {
                        x += (int)(mSpacingX + mChar.width);
                    }
                }
#endif
            }

            // Convert from pixel coordinates to local coordinates
            float scale = (fs > 0) ? 1f / fs : 1f;
            v.x = scale * ((x > maxX) ? x : maxX);
            v.y = scale * (y + lineHeight);
        }
        return(v);
    }
示例#10
0
    public Vector2 CalculatePrintedSize(string text, bool encoding, SymbolStyle symbolStyle)
    {
        if (mReplacement != null)
        {
            return(mReplacement.CalculatePrintedSize(text, encoding, symbolStyle));
        }
        Vector2 zero      = Vector2.zero;
        bool    isDynamic = this.isDynamic;

        if (isDynamic || (mFont != null && mFont.isValid && !string.IsNullOrEmpty(text)))
        {
            if (encoding)
            {
                text = NGUITools.StripSymbols(text);
            }
            if (isDynamic)
            {
                Font.textureRebuilt += OnFontChanged;
                // mDynamicFont.textureRebuildCallback = OnFontChanged;
                mDynamicFont.RequestCharactersInTexture(text, mDynamicFontSize, mDynamicFontStyle);
                // mDynamicFont.textureRebuildCallback = null;
                Font.textureRebuilt -= OnFontChanged;
            }
            int  length = text.Length;
            int  num    = 0;
            int  num2   = 0;
            int  num3   = 0;
            int  num4   = 0;
            int  size   = this.size;
            int  num5   = size + mSpacingY;
            bool flag   = encoding && symbolStyle != 0 && hasSymbols;
            for (int i = 0; i < length; i++)
            {
                char c = text[i];
                if (c == '\n')
                {
                    if (num2 > num)
                    {
                        num = num2;
                    }
                    num2  = 0;
                    num3 += num5;
                    num4  = 0;
                }
                else if (c < ' ')
                {
                    num4 = 0;
                }
                else if (!isDynamic)
                {
                    BMSymbol bMSymbol = (!flag) ? null : MatchSymbol(text, i, length);
                    if (bMSymbol == null)
                    {
                        BMGlyph glyph = mFont.GetGlyph(c);
                        if (glyph != null)
                        {
                            num2 += mSpacingX + ((num4 == 0) ? glyph.advance : (glyph.advance + glyph.GetKerning(num4)));
                            num4  = c;
                        }
                    }
                    else
                    {
                        num2 += mSpacingX + bMSymbol.width;
                        i    += bMSymbol.length - 1;
                        num4  = 0;
                    }
                }
                else if (mDynamicFont.GetCharacterInfo(c, out mChar, mDynamicFontSize, mDynamicFontStyle))
                {
                    num2 += (int)((float)mSpacingX + mChar.width);
                }
            }
            float num6 = (size <= 0) ? 1f : (1f / (float)size);
            zero.x = num6 * (float)((num2 <= num) ? num : num2);
            zero.y = num6 * (float)(num3 + num5);
        }
        return(zero);
    }