MyGUI 3.0.1

MyGUI_ResourceManualFont.cpp

Go to the documentation of this file.
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines