• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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_Common.h"
00026 #include "MyGUI_SkinManager.h"
00027 #include "MyGUI_RenderManager.h"
00028 #include "MyGUI_TextureUtility.h"
00029 
00030 namespace MyGUI
00031 {
00032 
00033     ResourceManualFont::ResourceManualFont() :
00034         mDefaultHeight(0),
00035         mTexture(nullptr)
00036     {
00037     }
00038 
00039     ResourceManualFont::~ResourceManualFont()
00040     {
00041     }
00042 
00043     GlyphInfo * ResourceManualFont::getGlyphInfo(Char _id)
00044     {
00045         for (VectorRangeInfo::iterator iter=mVectorRangeInfo.begin(); iter!=mVectorRangeInfo.end(); ++iter)
00046         {
00047             GlyphInfo * info = iter->getInfo(_id);
00048             if (info == nullptr) continue;
00049             return info;
00050         }
00051         // при ошибках возвращаем пробел
00052         return &mSpaceGlyphInfo;
00053     }
00054 
00055     void ResourceManualFont::checkTexture()
00056     {
00057         if (mTexture == nullptr)
00058         {
00059             RenderManager& render = RenderManager::getInstance();
00060             mTexture = render.getTexture(mSource);
00061             if (mTexture == nullptr)
00062             {
00063                 mTexture = render.createTexture(mSource);
00064                 mTexture->loadFromFile(mSource);
00065             }
00066         }
00067     }
00068 
00069     void ResourceManualFont::addGlyph(GlyphInfo * _info, Char _index, int _left, int _top, int _right, int _bottom, int _finalw, int _finalh, float _aspect, int _addHeight)
00070     {
00071         _info->codePoint = _index;
00072         _info->uvRect.left = (float)_left / (float)_finalw;  // u1
00073         _info->uvRect.top = (float)(_top + _addHeight) / (float)_finalh;  // v1
00074         _info->uvRect.right = (float)( _right ) / (float)_finalw; // u2
00075         _info->uvRect.bottom = ( _bottom + _addHeight ) / (float)_finalh; // v2
00076         _info->width = _right - _left;
00077     }
00078 
00079     void ResourceManualFont::addGlyph(Char _code, const IntCoord& _coord)
00080     {
00081         mVectorPairCodeCoord.push_back(PairCodeCoord(_code, _coord));
00082     }
00083 
00084     void ResourceManualFont::initialise()
00085     {
00086         if (mVectorPairCodeCoord.empty()) return;
00087 
00088         std::sort(mVectorPairCodeCoord.begin(), mVectorPairCodeCoord.end());
00089 
00090         const IntSize& size = texture_utility::getTextureSize(mSource);
00091         float aspect = (float)size.width / (float)size.height;
00092 
00093         Char code = mVectorPairCodeCoord.front().code;
00094         size_t count = mVectorPairCodeCoord.size();
00095         size_t first = 0;
00096 
00097         for (size_t pos=1; pos<count; ++pos)
00098         {
00099             // диапазон оборвался
00100             if (code + 1 != mVectorPairCodeCoord[pos].code)
00101             {
00102                 addRange(mVectorPairCodeCoord, first, pos-1, size.width, size.height, aspect);
00103                 code = mVectorPairCodeCoord[pos].code;
00104                 first = pos;
00105             }
00106             else
00107             {
00108                 code ++;
00109             }
00110         }
00111 
00112         addRange(mVectorPairCodeCoord, first, count-1, size.width, size.height, aspect);
00113 
00114         // уничтожаем буфер
00115         VectorPairCodeCoord tmp;
00116         std::swap(tmp, mVectorPairCodeCoord);
00117 
00118         checkTexture();
00119     }
00120 
00121     void ResourceManualFont::addRange(VectorPairCodeCoord& _info, size_t _first, size_t _last, int _width, int _height, float _aspect)
00122     {
00123         RangeInfo range = RangeInfo(_info[_first].code, _info[_last].code);
00124 
00125         for (size_t pos=_first; pos<=_last; ++pos)
00126         {
00127             GlyphInfo * info = range.getInfo(_info[pos].code);
00128             const IntCoord& coord = _info[pos].coord;
00129             addGlyph(info, _info[pos].code, coord.left, coord.top, coord.right(), coord.bottom(), _width, _height, _aspect);
00130 
00131             if (_info[pos].code == FontCodeType::Space)
00132                 mSpaceGlyphInfo = *info;
00133         }
00134 
00135         mVectorRangeInfo.push_back(range);
00136     }
00137 
00138     void ResourceManualFont::deserialization(xml::ElementPtr _node, Version _version)
00139     {
00140         Base::deserialization(_node, _version);
00141 
00142         xml::ElementEnumerator node = _node->getElementEnumerator();
00143         while (node.next())
00144         {
00145             if (node->getName() == "Property")
00146             {
00147                 const std::string& key = node->findAttribute("key");
00148                 const std::string& value = node->findAttribute("value");
00149                 if (key == "Source") mSource = value;
00150                 else if (key == "DefaultHeight") mDefaultHeight = utility::parseInt(value);
00151             }
00152             else if (node->getName() == "Codes")
00153             {
00154                 xml::ElementEnumerator range = node->getElementEnumerator();
00155                 while (range.next("Code"))
00156                 {
00157                     std::string range_value;
00158                     std::vector<std::string> parse_range;
00159                     // описане глифов
00160                     if (range->findAttribute("index", range_value))
00161                     {
00162                         Char id = 0;
00163                         if (range_value == "cursor")
00164                             id = FontCodeType::Cursor;
00165                         else if (range_value == "selected")
00166                             id = FontCodeType::Selected;
00167                         else if (range_value == "selected_back")
00168                             id = FontCodeType::SelectedBack;
00169                         else
00170                             id = utility::parseUInt(range_value);
00171 
00172                         addGlyph(id, utility::parseValue<IntCoord>(range->findAttribute("coord")));
00173                     }
00174                 }
00175             }
00176         }
00177 
00178         // инициализируем
00179         initialise();
00180     }
00181 
00182 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1