/// <summary> /// Helper function that retrieves the specified glyph, creating it if necessary. /// </summary> public BMGlyph GetGlyph(int index, bool createIfMissing) { // Get the requested glyph BMGlyph glyph = null; if (mDict.Count == 0) { // Populate the dictionary for faster access for (int i = 0, imax = mSaved.Count; i < imax; ++i) { BMGlyph bmg = mSaved[i]; mDict.Add(bmg.index, bmg); } } // Saved check is here so that the function call is not needed if it's true if (!mDict.TryGetValue(index, out glyph) && createIfMissing) { glyph = new BMGlyph(); glyph.index = index; mSaved.Add(glyph); mDict.Add(index, glyph); } return glyph; }
/// <summary> /// Trim the glyphs, ensuring that they will never go past the specified bounds. /// </summary> public void Trim(int xMin, int yMin, int xMax, int yMax) { if (isValid) { for (int i = 0, imax = mSaved.Count; i < imax; ++i) { BMGlyph glyph = mSaved[i]; if (glyph != null) glyph.Trim(xMin, yMin, xMax, yMax); } } }
private static void CreateFont() { if (Selection.objects == null) return; if (Selection.objects.Length == 0) { Debug.LogWarning("没有选中fnt文件,或者图片文件"); return; } // end if //至少需要保证选中文件的目录下面有fnt文件,否则不会生成字体 Font m_myFont = null; TextAsset m_data = null; string filePath = ""; Material mat = null; Texture2D tex = null; bool bln = false; //不管选中fnt、png、mat、fontsettings其中的任何一个,都可以创建字体 foreach (Object o in Selection.objects) { if (o.GetType() == typeof(TextAsset)) { m_data = o as TextAsset; bln = true; } else if (o.GetType() == typeof(Material)) { mat = o as Material; bln = true; } else if (o.GetType() == typeof(Texture2D)) { tex = o as Texture2D; bln = true; } else if (o.GetType() == typeof(Font)) { m_myFont = o as Font; bln = true; } // end if if (bln) { filePath = AssetDatabase.GetAssetPath(o); filePath = filePath.Substring(0, filePath.LastIndexOf('.')); } // end if } // end foreach //获取fnt文件,我们在这里加一次判断,为了可以直接选择图片也能导出字体 string dataPathName = filePath + ".fnt"; if (m_data == null) { m_data = (TextAsset)AssetDatabase.LoadAssetAtPath(dataPathName, typeof(TextAsset)); } // end if if (m_data != null) { string matPathName = filePath + ".mat"; string fontPathName = filePath + ".fontsettings"; string texPathName = filePath + ".png"; //获取图片,如果没有图片,不影响,可以生成之后,再手动设置 if (tex == null) { tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texPathName, typeof(Texture2D)); } // en dif if (tex == null) { Debug.LogWarning("没找到图片,或者图片名称和fnt文件名称不匹配"); } // end if //获取材质,如果没有则创建对应名字的材质 if (mat == null) { mat = (Material)AssetDatabase.LoadAssetAtPath(matPathName, typeof(Material)); } // end if if (mat == null) { mat = new Material(Shader.Find("GUI/Text Shader")); AssetDatabase.CreateAsset(mat, matPathName); } else { mat.shader = Shader.Find("GUI/Text Shader"); } // end if mat.SetTexture("_MainTex", tex); //获取font文件,如果没有则创建对应名字的font文件 if (m_myFont == null) { m_myFont = (Font)AssetDatabase.LoadAssetAtPath(fontPathName, typeof(Font)); } // end if if (m_myFont == null) { m_myFont = new Font(); AssetDatabase.CreateAsset(m_myFont, fontPathName); } // end if m_myFont.material = mat; BMFont mbFont = new BMFont(); //借助NGUI的类,读取字体fnt文件信息,可以不用自己去解析了 BMFontReader.Load(mbFont, m_data.name, m_data.bytes); CharacterInfo[] characterInfo = new CharacterInfo[mbFont.glyphs.Count]; for (int i = 0; i < mbFont.glyphs.Count; i++) { BMGlyph bmInfo = mbFont.glyphs[i]; CharacterInfo info = new CharacterInfo(); //设置ascii码 info.index = bmInfo.index; //设置字符映射到材质上的坐标 info.uvBottomLeft = new Vector2((float)bmInfo.x / mbFont.texWidth, 1f - (float)(bmInfo.y + bmInfo.height) / mbFont.texHeight); info.uvBottomRight = new Vector2((float)(bmInfo.x + bmInfo.width) / mbFont.texWidth, 1f - (float)(bmInfo.y + bmInfo.height) / mbFont.texHeight); info.uvTopLeft = new Vector2((float)bmInfo.x / mbFont.texWidth, 1f - (float)(bmInfo.y) / mbFont.texHeight); info.uvTopRight = new Vector2((float)(bmInfo.x + bmInfo.width) / mbFont.texWidth, 1f - (float)(bmInfo.y) / mbFont.texHeight); //设置字符顶点的偏移位置和宽高 info.minX = bmInfo.offsetX; info.minY = -bmInfo.offsetY - bmInfo.height; info.maxX = bmInfo.offsetX + bmInfo.width; info.maxY = -bmInfo.offsetY; //设置字符的宽度 info.advance = bmInfo.advance; characterInfo[i] = info; } // end for m_myFont.characterInfo = characterInfo; EditorUtility.SetDirty(m_myFont);//设置变更过的资源 EditorUtility.SetDirty(mat);//设置变更过的资源 AssetDatabase.SaveAssets();//保存变更的资源 AssetDatabase.Refresh();//刷新资源,貌似在Mac上不起作用 //由于上面fresh之后在编辑器中依然没有刷新,所以暂时想到这个方法, //先把生成的字体导出成一个包,然后再重新导入进来,这样就可以直接刷新了 //这是在Mac上遇到的,不知道Windows下面会不会出现,如果不出现可以把下面这一步注释掉 AssetDatabase.ExportPackage(fontPathName, "temp.unitypackage"); AssetDatabase.DeleteAsset(fontPathName); AssetDatabase.ImportPackage("temp.unitypackage", true); AssetDatabase.Refresh(); Debug.Log("创建字体成功"); } else { Debug.LogWarning("没有找到fnt文件,或者文件名称和图片名称不匹配"); } // end if } // end CreateFont
/// <summary> /// Reload the font data. /// </summary> static public 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", ""); } } } } }