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