bool GetCharacterInfo(char m_character, ref CustomCharacterInfo char_info) { if(m_character.Equals('\n') || m_character.Equals('\r')) { return true; } if(m_font != null) { if(!m_current_font_name.Equals(m_font.name)) { // Recalculate font's baseline value // Checks through all available alpha characters and uses the most common bottom y_axis value as the baseline for the font. #pragma warning disable Dictionary<float, int> baseline_values = new Dictionary<float, int>(); float baseline; foreach(CharacterInfo character in m_font.characterInfo) { // only check alpha characters (a-z, A-Z) if((character.index >= 97 && character.index < 123) || (character.index >= 65 && character.index < 91)) { baseline = -character.vert.y - character.vert.height; if(baseline_values.ContainsKey(baseline)) baseline_values[baseline] ++; else baseline_values[baseline] = 1; } } #pragma warning restore // Find most common baseline value used by the letters int idx=0; int highest_num=0, highest_idx=-1; float most_common_baseline = -1; foreach(int num in baseline_values.Values) { if(highest_idx == -1 || num > highest_num) { highest_idx = idx; highest_num = num; } idx++; } // Retrieve the most common value and use as baseline value idx=0; foreach(float baseline_key in baseline_values.Keys) { if(idx == highest_idx) { most_common_baseline = baseline_key; break; } idx++; } m_font_baseline = most_common_baseline; // Set font name to current, to ensure this check doesn't happen each time m_current_font_name = m_font.name; } CharacterInfo font_char_info = new CharacterInfo(); m_font.GetCharacterInfo(m_character, out font_char_info); #pragma warning disable char_info.flipped = font_char_info.flipped; char_info.uv = font_char_info.uv; char_info.vert = font_char_info.vert; char_info.width = font_char_info.width; // Scale char_info values char_info.vert.x /= FontScale; char_info.vert.y /= FontScale; char_info.vert.width /= FontScale; char_info.vert.height /= FontScale; char_info.width /= FontScale; if(font_char_info.width == 0) { // Invisible character info returned because character is not contained within the font Debug.LogWarning("Character '" + GetHumanReadableCharacterString(m_character) + "' not found. Check that font '" + m_font.name + "' supports this character."); } #pragma warning restore return true; } if(m_font_data_file != null) { if(m_custom_font_data == null || !m_font_data_file.name.Equals(m_current_font_data_file_name)) { // Setup m_custom_font_data for the custom font. #if !UNITY_WINRT if(m_font_data_file.text.Substring(0,5).Equals("<?xml")) { // Text file is in xml format m_current_font_data_file_name = m_font_data_file.name; m_custom_font_data = new CustomFontCharacterData(); XmlTextReader reader = new XmlTextReader(new StringReader(m_font_data_file.text)); int texture_width = 0; int texture_height = 0; int uv_x, uv_y; float width, height, xoffset, yoffset, xadvance; CustomCharacterInfo character_info; while(reader.Read()) { if(reader.IsStartElement()) { if(reader.Name.Equals("common")) { texture_width = int.Parse(reader.GetAttribute("scaleW")); texture_height = int.Parse(reader.GetAttribute("scaleH")); m_font_baseline = int.Parse(reader.GetAttribute("base")); } else if(reader.Name.Equals("char")) { uv_x = int.Parse(reader.GetAttribute("x")); uv_y = int.Parse(reader.GetAttribute("y")); width = float.Parse(reader.GetAttribute("width")); height = float.Parse(reader.GetAttribute("height")); xoffset = float.Parse(reader.GetAttribute("xoffset")); yoffset = float.Parse(reader.GetAttribute("yoffset")); xadvance = float.Parse(reader.GetAttribute("xadvance")); character_info = new CustomCharacterInfo(); character_info.flipped = false; character_info.uv = new Rect((float) uv_x / (float) texture_width, 1 - ((float)uv_y / (float)texture_height) - (float)height/(float)texture_height, (float)width/(float)texture_width, (float)height/(float)texture_height); character_info.vert = new Rect(xoffset,-yoffset,width, -height); character_info.width = xadvance; m_custom_font_data.m_character_infos.Add( int.Parse(reader.GetAttribute("id")), character_info); } } } } else #endif if(m_font_data_file.text.Substring(0,4).Equals("info")) { // Plain txt format m_current_font_data_file_name = m_font_data_file.name; m_custom_font_data = new CustomFontCharacterData(); int texture_width = 0; int texture_height = 0; int uv_x, uv_y; float width, height, xoffset, yoffset, xadvance; CustomCharacterInfo character_info; string[] data_fields; string[] text_lines = m_font_data_file.text.Split(new char[]{'\n'}); foreach(string font_data in text_lines) { if(font_data.Length >= 5 && font_data.Substring(0,5).Equals("char ")) { // character data line data_fields = ParseFieldData(font_data, new string[]{"id=", "x=", "y=", "width=", "height=", "xoffset=", "yoffset=", "xadvance="}); uv_x = int.Parse(data_fields[1]); uv_y = int.Parse(data_fields[2]); width = float.Parse(data_fields[3]); height = float.Parse(data_fields[4]); xoffset = float.Parse(data_fields[5]); yoffset = float.Parse(data_fields[6]); xadvance = float.Parse(data_fields[7]); character_info = new CustomCharacterInfo(); character_info.flipped = false; character_info.uv = new Rect((float) uv_x / (float) texture_width, 1 - ((float)uv_y / (float)texture_height) - (float)height/(float)texture_height, (float)width/(float)texture_width, (float)height/(float)texture_height); character_info.vert = new Rect(xoffset,-yoffset +1,width, -height); character_info.width = xadvance; m_custom_font_data.m_character_infos.Add( int.Parse(data_fields[0]), character_info); } else if(font_data.Length >= 6 && font_data.Substring(0,6).Equals("common")) { data_fields = ParseFieldData(font_data, new string[]{"scaleW=", "scaleH=", "base="}); texture_width = int.Parse(data_fields[0]); texture_height = int.Parse(data_fields[1]); m_font_baseline = int.Parse(data_fields[2]); } } } } if(m_custom_font_data.m_character_infos.ContainsKey((int) m_character)) { ((CustomCharacterInfo) m_custom_font_data.m_character_infos[(int)m_character]).ScaleClone(FontScale, ref char_info); return true; } } return false; }
public void ClearFontCharacterData() { if(m_custom_font_data != null) { m_custom_font_data.m_character_infos.Clear(); m_custom_font_data = null; } }