1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_ResourceManualFont.h"
9 #include "MyGUI_SkinManager.h"
10 #include "MyGUI_RenderManager.h"
11 #include "MyGUI_TextureUtility.h"
12 
13 namespace MyGUI
14 {
15 
ResourceManualFont()16 	ResourceManualFont::ResourceManualFont() :
17 		mDefaultHeight(0),
18 		mSubstituteGlyphInfo(nullptr),
19 		mTexture(nullptr)
20 	{
21 	}
22 
getGlyphInfo(Char _id)23 	GlyphInfo* ResourceManualFont::getGlyphInfo(Char _id)
24 	{
25 		CharMap::iterator iter = mCharMap.find(_id);
26 
27 		if (iter != mCharMap.end())
28 			return &iter->second;
29 
30 		return mSubstituteGlyphInfo;
31 	}
32 
loadTexture()33 	void ResourceManualFont::loadTexture()
34 	{
35 		if (mTexture == nullptr)
36 		{
37 			RenderManager& render = RenderManager::getInstance();
38 			mTexture = render.getTexture(mSource);
39 			if (mTexture == nullptr)
40 			{
41 				mTexture = render.createTexture(mSource);
42 				if (mTexture != nullptr)
43 					mTexture->loadFromFile(mSource);
44 			}
45 		}
46 	}
47 
deserialization(xml::ElementPtr _node,Version _version)48 	void ResourceManualFont::deserialization(xml::ElementPtr _node, Version _version)
49 	{
50 		Base::deserialization(_node, _version);
51 
52 		xml::ElementEnumerator node = _node->getElementEnumerator();
53 		while (node.next())
54 		{
55 			if (node->getName() == "Property")
56 			{
57 				const std::string& key = node->findAttribute("key");
58 				const std::string& value = node->findAttribute("value");
59 				if (key == "Source") mSource = value;
60 				else if (key == "DefaultHeight") mDefaultHeight = utility::parseInt(value);
61 			}
62 		}
63 
64 		loadTexture();
65 
66 		if (mTexture != nullptr)
67 		{
68 			int textureWidth = mTexture->getWidth();
69 			int textureHeight = mTexture->getHeight();
70 
71 			node = _node->getElementEnumerator();
72 			while (node.next())
73 			{
74 				if (node->getName() == "Codes")
75 				{
76 					xml::ElementEnumerator element = node->getElementEnumerator();
77 					while (element.next("Code"))
78 					{
79 						std::string value;
80 						// описане глифов
81 						if (element->findAttribute("index", value))
82 						{
83 							Char id = 0;
84 							if (value == "cursor")
85 								id = static_cast<Char>(FontCodeType::Cursor);
86 							else if (value == "selected")
87 								id = static_cast<Char>(FontCodeType::Selected);
88 							else if (value == "selected_back")
89 								id = static_cast<Char>(FontCodeType::SelectedBack);
90 							else if (value == "substitute")
91 								id = static_cast<Char>(FontCodeType::NotDefined);
92 							else
93 								id = utility::parseUInt(value);
94 
95 							float advance(utility::parseValue<float>(element->findAttribute("advance")));
96 							FloatPoint bearing(utility::parseValue<FloatPoint>(element->findAttribute("bearing")));
97 
98 							// texture coordinates
99 							FloatCoord coord(utility::parseValue<FloatCoord>(element->findAttribute("coord")));
100 
101 							// glyph size, default to texture coordinate size
102 							std::string sizeString;
103 							FloatSize size(coord.width, coord.height);
104 							if (element->findAttribute("size", sizeString))
105 							{
106 								size = utility::parseValue<FloatSize>(sizeString);
107 							}
108 
109 							if (advance == 0.0f)
110 								advance = size.width;
111 
112 							GlyphInfo& glyphInfo = mCharMap.insert(CharMap::value_type(id, GlyphInfo(
113 								id,
114 								size.width,
115 								size.height,
116 								advance,
117 								bearing.left,
118 								bearing.top,
119 								FloatRect(
120 									coord.left / textureWidth,
121 									coord.top / textureHeight,
122 									coord.right() / textureWidth,
123 									coord.bottom() / textureHeight)
124 								))).first->second;
125 
126 							if (id == FontCodeType::NotDefined)
127 								mSubstituteGlyphInfo = &glyphInfo;
128 						}
129 					}
130 				}
131 			}
132 		}
133 	}
134 
getTextureFont()135 	ITexture* ResourceManualFont::getTextureFont()
136 	{
137 		return mTexture;
138 	}
139 
getDefaultHeight()140 	int ResourceManualFont::getDefaultHeight()
141 	{
142 		return mDefaultHeight;
143 	}
144 
setSource(const std::string & value)145 	void ResourceManualFont::setSource(const std::string& value)
146 	{
147 		mTexture = nullptr;
148 		mSource = value;
149 		loadTexture();
150 	}
151 
setTexture(ITexture * texture)152 	void ResourceManualFont::setTexture(ITexture *texture)
153 	{
154 		mTexture = texture;
155 		mSource.clear();
156 	}
157 
setDefaultHeight(int value)158 	void ResourceManualFont::setDefaultHeight(int value)
159 	{
160 		mDefaultHeight = value;
161 	}
162 
addGlyphInfo(Char id,const GlyphInfo & info)163 	void ResourceManualFont::addGlyphInfo(Char id, const GlyphInfo& info)
164 	{
165 		GlyphInfo& inserted = mCharMap.insert(CharMap::value_type(id, info)).first->second;
166 
167 		if (id == FontCodeType::NotDefined)
168 			mSubstituteGlyphInfo = &inserted;
169 	}
170 
171 } // namespace MyGUI
172