MyGUI
3.2.0
|
00001 00006 /* 00007 This file is part of MyGUI. 00008 00009 MyGUI is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU Lesser General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 MyGUI is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 #include "MyGUI_Precompiled.h" 00023 #include "MyGUI_ResourceManualFont.h" 00024 #include "MyGUI_SkinManager.h" 00025 #include "MyGUI_RenderManager.h" 00026 #include "MyGUI_TextureUtility.h" 00027 00028 namespace MyGUI 00029 { 00030 00031 ResourceManualFont::ResourceManualFont() : 00032 mDefaultHeight(0), 00033 mTexture(nullptr) 00034 { 00035 } 00036 00037 ResourceManualFont::~ResourceManualFont() 00038 { 00039 } 00040 00041 GlyphInfo* ResourceManualFont::getGlyphInfo(Char _id) 00042 { 00043 for (VectorRangeInfo::iterator iter = mVectorRangeInfo.begin(); iter != mVectorRangeInfo.end(); ++iter) 00044 { 00045 GlyphInfo* info = iter->getInfo(_id); 00046 if (info == nullptr) continue; 00047 return info; 00048 } 00049 // при ошибках возвращаем пробел 00050 return &mSpaceGlyphInfo; 00051 } 00052 00053 void ResourceManualFont::checkTexture() 00054 { 00055 if (mTexture == nullptr) 00056 { 00057 RenderManager& render = RenderManager::getInstance(); 00058 mTexture = render.getTexture(mSource); 00059 if (mTexture == nullptr) 00060 { 00061 mTexture = render.createTexture(mSource); 00062 mTexture->loadFromFile(mSource); 00063 } 00064 } 00065 } 00066 00067 void ResourceManualFont::addGlyph(GlyphInfo* _info, Char _index, int _left, int _top, int _right, int _bottom, int _finalw, int _finalh, float _aspect, int _addHeight) const 00068 { 00069 _info->codePoint = _index; 00070 _info->uvRect.left = (float)_left / (float)_finalw; // u1 00071 _info->uvRect.top = (float)(_top + _addHeight) / (float)_finalh; // v1 00072 _info->uvRect.right = (float)( _right ) / (float)_finalw; // u2 00073 _info->uvRect.bottom = ( _bottom + _addHeight ) / (float)_finalh; // v2 00074 _info->width = _right - _left; 00075 } 00076 00077 void ResourceManualFont::addGlyph(Char _code, const IntCoord& _coord) 00078 { 00079 mVectorPairCodeCoord.push_back(PairCodeCoord(_code, _coord)); 00080 } 00081 00082 void ResourceManualFont::initialise() 00083 { 00084 if (mVectorPairCodeCoord.empty()) return; 00085 00086 std::sort(mVectorPairCodeCoord.begin(), mVectorPairCodeCoord.end()); 00087 00088 const IntSize& size = texture_utility::getTextureSize(mSource); 00089 float aspect = (float)size.width / (float)size.height; 00090 00091 Char code = mVectorPairCodeCoord.front().code; 00092 size_t count = mVectorPairCodeCoord.size(); 00093 size_t first = 0; 00094 00095 for (size_t pos = 1; pos < count; ++pos) 00096 { 00097 // диапазон оборвался 00098 if (code + 1 != mVectorPairCodeCoord[pos].code) 00099 { 00100 addRange(mVectorPairCodeCoord, first, pos - 1, size.width, size.height, aspect); 00101 code = mVectorPairCodeCoord[pos].code; 00102 first = pos; 00103 } 00104 else 00105 { 00106 code ++; 00107 } 00108 } 00109 00110 addRange(mVectorPairCodeCoord, first, count - 1, size.width, size.height, aspect); 00111 00112 // уничтожаем буфер 00113 VectorPairCodeCoord tmp; 00114 std::swap(tmp, mVectorPairCodeCoord); 00115 00116 checkTexture(); 00117 } 00118 00119 void ResourceManualFont::addRange(VectorPairCodeCoord& _info, size_t _first, size_t _last, int _width, int _height, float _aspect) 00120 { 00121 RangeInfo range = RangeInfo(_info[_first].code, _info[_last].code); 00122 00123 for (size_t pos = _first; pos <= _last; ++pos) 00124 { 00125 GlyphInfo* info = range.getInfo(_info[pos].code); 00126 const IntCoord& coord = _info[pos].coord; 00127 addGlyph(info, _info[pos].code, coord.left, coord.top, coord.right(), coord.bottom(), _width, _height, _aspect); 00128 00129 if (_info[pos].code == FontCodeType::Space) 00130 mSpaceGlyphInfo = *info; 00131 } 00132 00133 mVectorRangeInfo.push_back(range); 00134 } 00135 00136 void ResourceManualFont::deserialization(xml::ElementPtr _node, Version _version) 00137 { 00138 Base::deserialization(_node, _version); 00139 00140 xml::ElementEnumerator node = _node->getElementEnumerator(); 00141 while (node.next()) 00142 { 00143 if (node->getName() == "Property") 00144 { 00145 const std::string& key = node->findAttribute("key"); 00146 const std::string& value = node->findAttribute("value"); 00147 if (key == "Source") mSource = value; 00148 else if (key == "DefaultHeight") mDefaultHeight = utility::parseInt(value); 00149 } 00150 else if (node->getName() == "Codes") 00151 { 00152 xml::ElementEnumerator range = node->getElementEnumerator(); 00153 while (range.next("Code")) 00154 { 00155 std::string range_value; 00156 std::vector<std::string> parse_range; 00157 // описане глифов 00158 if (range->findAttribute("index", range_value)) 00159 { 00160 Char id = 0; 00161 if (range_value == "cursor") 00162 id = FontCodeType::Cursor; 00163 else if (range_value == "selected") 00164 id = FontCodeType::Selected; 00165 else if (range_value == "selected_back") 00166 id = FontCodeType::SelectedBack; 00167 else 00168 id = utility::parseUInt(range_value); 00169 00170 addGlyph(id, utility::parseValue<IntCoord>(range->findAttribute("coord"))); 00171 } 00172 } 00173 } 00174 } 00175 00176 // инициализируем 00177 initialise(); 00178 } 00179 00180 ITexture* ResourceManualFont::getTextureFont() 00181 { 00182 return mTexture; 00183 } 00184 00185 int ResourceManualFont::getDefaultHeight() 00186 { 00187 return mDefaultHeight; 00188 } 00189 00190 } // namespace MyGUI