nux-1.14.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "GLResource.h" 00024 #include "GLResourceManager.h" 00025 #include "GLTextureResourceManager.h" 00026 #include "GraphicsEngine.h" 00027 #include "FontTexture.h" 00028 00029 namespace nux 00030 { 00031 00032 NUX_IMPLEMENT_OBJECT_TYPE (FontTexture); 00033 00034 const int CURSOR_OFFSET = 0; 00035 00036 FontTexture::FontTexture (const TCHAR *FontFile, NUX_FILE_LINE_DECL) 00037 : Object (true, NUX_FILE_LINE_PARAM) 00038 { 00039 NString FontPath = GNuxGraphicsResources.FindResourceLocation (FontFile); 00040 00041 std::filebuf fb; 00042 fb.open (FontPath.GetTCharPtr(), std::ios::in); 00043 std::istream is (&fb); 00044 00045 BMFontParseFNT (is); 00046 } 00047 00048 FontTexture::FontTexture (int width, int height, BYTE *Texture) 00049 { 00050 00051 } 00052 00053 FontTexture::~FontTexture() 00054 { 00055 std::vector<BaseTexture*>::iterator it; 00056 for(it = TextureArray.begin(); it != TextureArray.end(); it++) 00057 { 00058 (*it)->UnReference (); 00059 } 00060 TextureArray.clear(); 00061 } 00062 00063 int FontTexture::GetCharWidth (const TCHAR &c) const 00064 { 00065 int ascii = c & 0xff; 00066 nuxAssert (ascii < m_Charset.NumChar); 00067 00068 if (ascii >= m_Charset.NumChar) 00069 return 0; 00070 00071 // XAdvance = abcA + abcB + abcC 00072 return m_Charset.Chars[ascii].XAdvance; 00073 } 00074 00075 int FontTexture::GetStringWidth (const NString &str) const 00076 { 00077 // unsigned int total = 0; 00078 // for (unsigned int i = 0; i != (unsigned int)str.size(); ++i) 00079 // { 00080 // total += GetCharWidth(str[i]); 00081 // } 00082 // return total; 00083 return GetCharStringWidth (str.GetTCharPtr() ); 00084 } 00085 00086 int FontTexture::GetCharStringWidth (const TCHAR *str) const 00087 { 00088 if ( (str == 0) || (NString (str) == NString (TEXT ("") ) ) ) 00089 return 0; 00090 00091 unsigned int total = 0; 00092 00093 for (int i = 0; ; ++i) 00094 { 00095 if (str[i] == 0) 00096 return total; 00097 00098 total += GetCharWidth (str[i]); 00099 } 00100 00101 return total; 00102 } 00103 00104 int FontTexture::GetStringWidth (const NString &str, int num_char_to_compute) const 00105 { 00106 return GetCharStringWidth (str.GetTCharPtr(), num_char_to_compute); 00107 } 00108 00109 int FontTexture::GetCharStringWidth (const TCHAR *str, int num_char_to_compute) const 00110 { 00111 if ( (str == 0) || (NString (str) == NString (TEXT ("") ) ) ) 00112 return 0; 00113 00114 int num_chars = num_char_to_compute; 00115 00116 if (num_chars <= 0) 00117 { 00118 return 0; 00119 } 00120 00121 int total = 0; 00122 00123 for (int i = 0; i < num_chars; ++i) 00124 { 00125 if (str[i] == 0) 00126 return total; 00127 00128 total += GetCharWidth (str[i]); 00129 } 00130 00131 return total; 00132 } 00133 00134 int FontTexture::GetFontHeight() 00135 { 00136 return m_Charset.FontHeight; 00137 } 00138 00139 bool FontTexture::BMFontParseFNT ( std::istream &Stream ) 00140 { 00141 std::string Line; 00142 int KerningIndex = 0; 00143 00144 while ( !Stream.eof() ) 00145 { 00146 std::getline ( Stream, Line ); 00147 00148 unsigned int line_size = (unsigned int) Line.length(); 00149 TCHAR *tc = new TCHAR[line_size+1]; 00150 const TCHAR *Stream = tc; 00151 Memcpy (tc, Line.c_str(), line_size + 1); 00152 tc[line_size] = 0; 00153 00154 if ( ParseCommand (&Stream, TEXT ("common") ) /*Read == "common"*/) 00155 { 00156 Parse_bool (tc, TEXT ("Bold="), m_Charset.bold); 00157 Parse_bool (tc, TEXT ("Italic="), m_Charset.italic); 00158 Parse_u16 (tc, TEXT ("base="), m_Charset.Base); 00159 Parse_u16 (tc, TEXT ("scaleW="), m_Charset.Width); 00160 Parse_u16 (tc, TEXT ("scaleH="), m_Charset.Height); 00161 Parse_u16 (tc, TEXT ("NumPages="), m_Charset.Pages); 00162 Parse_u16 (tc, TEXT ("FontHeight="), m_Charset.FontHeight); 00163 Parse_u16 (tc, TEXT ("Ascent="), m_Charset.Ascent); 00164 Parse_u16 (tc, TEXT ("Descent="), m_Charset.Descent); 00165 Parse_int (tc, TEXT ("AvgCharWidth="), m_Charset.AvgCharWidth); 00166 Parse_int (tc, TEXT ("MaxCharWidth="), m_Charset.MaxCharWidth); 00167 Parse_int (tc, TEXT ("InternalLeading="), m_Charset.InternalLeading); 00168 Parse_int (tc, TEXT ("ExternalLeading="), m_Charset.ExternalLeading); 00169 // Constant for now... Should be read from the font file 00170 m_Charset.NumChar = 256; 00171 } 00172 else if (ParseCommand (&Stream, TEXT ("char") ) ) 00173 { 00174 00175 unsigned short CharID = 0; 00176 00177 Parse_u16 (tc, TEXT ("id="), CharID); 00178 Parse_u16 (tc, TEXT ("x="), m_Charset.Chars[CharID].x); 00179 Parse_u16 (tc, TEXT ("y="), m_Charset.Chars[CharID].y); 00180 Parse_u16 (tc, TEXT ("width="), m_Charset.Chars[CharID].Width); 00181 Parse_u16 (tc, TEXT ("height="), m_Charset.Chars[CharID].Height); 00182 Parse_s16 (tc, TEXT ("xoffset="), m_Charset.Chars[CharID].XOffset); 00183 Parse_s16 (tc, TEXT ("yoffset="), m_Charset.Chars[CharID].YOffset); 00184 Parse_s16 (tc, TEXT ("xadvance="), m_Charset.Chars[CharID].XAdvance); 00185 Parse_s16 (tc, TEXT ("abcA="), m_Charset.Chars[CharID].abcA); 00186 Parse_s16 (tc, TEXT ("abcB="), m_Charset.Chars[CharID].abcB); 00187 Parse_s16 (tc, TEXT ("abcC="), m_Charset.Chars[CharID].abcC); 00188 Parse_u16 (tc, TEXT ("page="), m_Charset.Chars[CharID].page); 00189 } 00190 else if ( ParseCommand (&Stream, TEXT ("Kerning") ) ) 00191 { 00192 Parse_u16 (tc, "count=", m_Charset.NumKerningPairs); 00193 00194 if (m_Charset.NumKerningPairs > 0) 00195 m_Charset.Kerning = new KerningPair[m_Charset.NumKerningPairs]; 00196 } 00197 else if ( ParseCommand (&Stream, TEXT ("KerningPair") ) ) 00198 { 00199 if (KerningIndex < m_Charset.NumKerningPairs) 00200 { 00201 Parse_u16 (tc, "first=", m_Charset.Kerning[KerningIndex].first); 00202 Parse_u16 (tc, "second=", m_Charset.Kerning[KerningIndex].second); 00203 Parse_s16 (tc, "amount=", m_Charset.Kerning[KerningIndex].amount); 00204 KerningIndex++; 00205 } 00206 } 00207 else if ( ParseCommand (&Stream, TEXT ("Texture") ) ) 00208 { 00209 TCHAR texture[256]; 00210 00211 if (ParseLine (&Stream, texture, 256) ) 00212 { 00213 // FilePath FontPath; 00214 // FontPath.AddSearchPath(""); // for case where fully qualified path is given 00215 // FontPath.AddSearchPath("."); 00216 // FontPath.AddSearchPath("../Fonts"); 00217 00218 #ifdef UNICODE 00219 NString font_texture_file = GNuxGraphicsResources.FindResourceLocation (texture); 00220 #else 00221 NString font_texture_file = GNuxGraphicsResources.FindResourceLocation (texture); 00222 #endif 00223 00224 TextureRectangle *Texture = new TextureRectangle (NUX_TRACKER_LOCATION); 00225 NBitmapData* bitmap_data = LoadImageFile(font_texture_file.GetTCharPtr ()); 00226 00227 if (bitmap_data) 00228 Texture->Update (bitmap_data, false); 00229 00230 delete bitmap_data; 00231 TextureArray.push_back (Texture); 00232 } 00233 } 00234 00235 delete [] tc; 00236 } 00237 00238 return true; 00239 } 00240 00241 // CursorPosToX (similar to ScriptStringCPtoX from Microsoft UniScript) 00242 // The CursorPosToX function returns the x-coordinate for the leading or trailing edge of a character position. 00243 00244 // Parameters 00245 // icp 00246 // [in] Character position in the string. 00247 // fTrailing 00248 // [in] Indicates the edge of the icp that corresponds to the x coordinate. If TRUE, it indicates the trailing edge. If FALSE, it indicates the leading edge. 00249 // pX 00250 // [out] Pointer to a variable that receives the corresponding x coordinate for the icp. 00251 // 00252 // Return Values 00253 // If the function succeeds, it returns S_OK. 00254 // If the function fails, it returns an HRESULT. 00255 // The return value can be tested with the SUCCEEDED and FAILED macros. 00256 bool FontTexture::CursorPosToX (const NString &Str, 00257 int icp, 00258 bool fTrailing, 00259 int *pX) 00260 { 00261 if (icp > (int) Str.Size() ) 00262 return false; 00263 00264 if (fTrailing) 00265 // get pX at the right of the character at position icp 00266 *pX = GetStringWidth (Str, icp + 1); 00267 else 00268 // get pX at the left of the character at position icp 00269 *pX = GetStringWidth (Str, icp); 00270 00271 return true; 00272 } 00273 00274 // XToCursorPosition (similar to ScriptStringXtoCP from Microsoft UniScript) 00275 // The XToCursorPosition function converts an x-coordinate to a character position. 00276 // 00277 // Parameters 00278 // iX 00279 // [in] Specifies the x coordinate. 00280 // FirstVisibleCharIndex, 00281 // [in] Index of the first visible character in the text box 00282 // piCh 00283 // [out] Pointer to a variable that receives the character position corresponding to iX. 00284 // piTrailing 00285 // [out] Pointer to a variable that receives an indicator whether the position is the leading or trailing edge of the character. 00286 // 00287 // Return Values 00288 // If the function is successful, it returns S_OK. 00289 // If the function fails, it returns an HRESULT. 00290 // The return value can be tested with the SUCCEEDED and FAILED macros. 00291 bool FontTexture::XToCursorPosition (const NString &Str, 00292 int iX, 00293 unsigned int FirstVisibleCharIndex, 00294 int *piCh, 00295 int *piTrailing) 00296 { 00297 unsigned int num_chars; 00298 num_chars = (unsigned int) Str.Size(); 00299 nuxAssert (FirstVisibleCharIndex < num_chars); 00300 00301 *piCh = 0; 00302 *piTrailing = 0; 00303 00304 unsigned int total = 0; 00305 00306 if (iX == 0) 00307 { 00308 *piCh = 0; 00309 *piTrailing = 0; 00310 return true; 00311 } 00312 00313 00314 unsigned int X = iX; 00315 00316 for (unsigned int i = 0; i < FirstVisibleCharIndex; ++i) 00317 { 00318 X += GetCharWidth (Str[i]); 00319 } 00320 00321 for (unsigned int i = 0; i < num_chars; ++i) 00322 { 00323 unsigned int s = GetCharWidth (Str[i]); 00324 00325 if (i >= FirstVisibleCharIndex) 00326 { 00327 if (total == X) 00328 { 00329 *piCh = i; 00330 *piTrailing = 0; 00331 return true; 00332 } 00333 else if (total + s / 2 > X) 00334 { 00335 *piCh = i; 00336 *piTrailing = 0; 00337 return true; 00338 } 00339 00340 else if (total + GetCharWidth (Str[i+1]) / 2 > X) 00341 { 00342 *piCh = i + 1; 00343 *piTrailing = 0; 00344 return true; 00345 } 00346 } 00347 00348 total += s; 00349 } 00350 00351 return false; 00352 } 00353 00354 const Charset &FontTexture::GetFontInfo() const 00355 { 00356 return m_Charset; 00357 } 00358 00359 }