28 #ifdef MYGUI_USE_FREETYPE
30 #include FT_FREETYPE_H
32 #endif // MYGUI_USE_FREETYPE
46 mAntialiasColour(false),
60 if (mTexture !=
nullptr)
69 for (VectorRangeInfo::iterator iter=mVectorRangeInfo.begin(); iter!=mVectorRangeInfo.end(); ++iter)
72 if (info ==
nullptr)
continue;
76 return &mSpaceGlyphInfo;
79 void ResourceTrueTypeFont::addGlyph(
GlyphInfo * _info,
Char _index,
int _left,
int _top,
int _right,
int _bottom,
int _finalw,
int _finalh,
float _aspect,
int _addHeight)
82 _info->
uvRect.
left = (float)_left / (
float)_finalw;
83 _info->
uvRect.
top = (float)(_top + _addHeight) / (float)_finalh;
84 _info->
uvRect.
right = (float)( _right ) / (float)_finalw;
85 _info->
uvRect.
bottom = ( _bottom + _addHeight ) / (
float)_finalh;
86 _info->
width = _right - _left;
89 uint8* ResourceTrueTypeFont::writeData(
uint8* _pDest,
unsigned char _luminance,
unsigned char _alpha,
bool _rgba)
93 *_pDest++ = _luminance;
94 *_pDest++ = _luminance;
95 *_pDest++ = _luminance;
100 *_pDest++ = _luminance;
106 void ResourceTrueTypeFont::initialise()
109 #ifndef MYGUI_USE_FREETYPE
111 MYGUI_LOG(Error,
"ResourceTrueTypeFont '" <<
getResourceName() <<
"' - Ttf font disabled. Define MYGUI_USE_FREETYE if you need ttf fonts.");
113 #else // MYGUI_USE_FREETYPE
118 FT_Library ftLibrary;
120 if ( FT_Init_FreeType( &ftLibrary ) )
MYGUI_EXCEPT(
"Could not init FreeType library!");
129 size_t datasize = datastream->size();
131 datastream->read(data, datasize);
134 if ( FT_New_Memory_Face( ftLibrary, data, (FT_Long)datasize, 0, &face ) )
138 FT_F26Dot6 ftSize = (FT_F26Dot6)(mTtfSize * (1 << 6));
139 if ( FT_Set_Char_Size( face, ftSize, 0, mTtfResolution, mTtfResolution ) )
142 int max_height = 0, max_bear = 0;
144 int spec_len = mCursorWidth + mSelectionWidth + mSelectionWidth + mSpaceWidth + mTabWidth + (mDistance * 5);
145 int len = mDistance + spec_len;
150 while (mTtfSize*mTtfResolution > finalWidth*6) finalWidth *= 2;
152 for (VectorRangeInfo::iterator iter=mVectorRangeInfo.begin(); iter!=mVectorRangeInfo.end(); ++iter)
154 for (
Char index=iter->first; index<=iter->last; ++index)
158 if (checkHidePointCode(index))
continue;
160 if (FT_Load_Char( face, index, FT_LOAD_RENDER ))
continue;
161 if (
nullptr == face->glyph->bitmap.buffer)
continue;
162 FT_Int advance = (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 );
164 if ( ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ) > max_height )
165 max_height = ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY );
167 if ( face->glyph->metrics.horiBearingY > max_bear )
168 max_bear = face->glyph->metrics.horiBearingY;
170 len += (advance + mDistance);
171 if (
int(finalWidth - 1) < (len + advance + mDistance) ) { height ++; len = mDistance;}
179 size_t finalHeight = (height+1) * (max_height + mDistance) + mDistance;
182 while (finalHeight > finalWidth)
189 size_t needHeight = 1;
190 while (needHeight < finalHeight) needHeight <<= 1;
191 finalHeight = needHeight;
193 float textureAspect = (float)finalWidth / (
float)finalHeight;
199 const size_t pixel_bytes = rgbaMode ? 4 : 2;
200 size_t data_width = finalWidth * pixel_bytes;
201 size_t data_size = finalWidth * finalHeight * pixel_bytes;
203 MYGUI_LOG(Info,
"ResourceTrueTypeFont '" <<
getResourceName() <<
"' using texture size " << finalWidth <<
" x " << finalHeight);
204 MYGUI_LOG(Info,
"ResourceTrueTypeFont '" <<
getResourceName() <<
"' using real height " << max_height <<
" pixels");
205 mHeightPix = max_height;
209 uint8* dest = imageData;
211 for (
size_t i = 0; i < data_size; i += pixel_bytes)
213 dest = writeData(dest, 0xFF, 0x00, rgbaMode);
224 advance = mSpaceWidth;
227 if (
int(finalWidth - 1) < (len + advance + mDistance) ) { height += max_height + mDistance; len = mDistance; }
229 for (
int j = 0; j < max_height; j++ )
231 int row = j + (int)height;
232 uint8* pDest = &imageData[(row * data_width) + len * pixel_bytes];
233 for (
int k = 0; k < advance; k++ )
239 addGlyph(&mSpaceGlyphInfo,
FontCodeType::Space, len, height, len + advance, height + max_height, finalWidth, finalHeight, textureAspect, mOffsetHeight);
240 len += (advance + mDistance);
248 if (
int(finalWidth - 1) < (len + advance + mDistance) ) { height += max_height + mDistance; len = mDistance; }
250 for (
int j = 0; j < max_height; j++ )
252 int row = j + (int)height;
253 uint8* pDest = &imageData[(row * data_width) + len * pixel_bytes];
254 for (
int k = 0; k < advance; k++ )
260 addGlyph(&mTabGlyphInfo,
FontCodeType::Tab, len, height, len + advance, height + max_height, finalWidth, finalHeight, textureAspect, mOffsetHeight);
261 len += (advance + mDistance);
266 advance = mSelectionWidth;
267 for (
int j = 0; j < max_height; j++ )
269 int row = j + (int)height;
270 uint8* pDest = &imageData[(row * data_width) + len * pixel_bytes];
271 for (
int k = 0; k < advance; k++ )
278 if (
int(finalWidth - 1) < (len + advance + mDistance) ) { height += max_height + mDistance; len = mDistance; }
280 addGlyph(&mSelectGlyphInfo,
FontCodeType::Selected, len, height, len + advance, height + max_height, finalWidth, finalHeight, textureAspect, mOffsetHeight);
281 len += (advance + mDistance);
286 advance = mSelectionWidth;
289 if (
int(finalWidth - 1) < (len + advance + mDistance) ) { height += max_height + mDistance; len = mDistance; }
291 for (
int j = 0; j < max_height; j++ )
293 int row = j + (int)height;
294 uint8* pDest = &imageData[(row * data_width) + len * pixel_bytes];
295 for (
int k = 0; k < advance; k++ )
301 addGlyph(&mSelectDeactiveGlyphInfo,
FontCodeType::SelectedBack, len, height, len + advance, height + max_height, finalWidth, finalHeight, textureAspect, mOffsetHeight);
302 len += (advance + mDistance);
307 advance = mCursorWidth;
310 if (
int(finalWidth - 1) < (len + advance + mDistance) ) { height += max_height + mDistance; len = mDistance; }
312 for (
int j = 0; j < max_height; j++ )
314 int row = j + (int)height;
315 uint8* pDest = &imageData[(row * data_width) + len * pixel_bytes];
316 for (
int k = 0; k < advance; k++ )
318 pDest = writeData(pDest, (k&1) ? 0 : 0xFF,
FONT_MASK_CHAR, rgbaMode);
322 addGlyph(&mCursorGlyphInfo,
FontCodeType::Cursor, len, height, len + advance, height + max_height, finalWidth, finalHeight, textureAspect, mOffsetHeight);
323 len += (advance + mDistance);
329 for (VectorRangeInfo::iterator iter=mVectorRangeInfo.begin(); iter!=mVectorRangeInfo.end(); ++iter)
332 for (
Char index=iter->first; index<=iter->last; ++index, ++pos)
335 if (checkHidePointCode(index))
continue;
337 GlyphInfo& info = iter->range.at(pos);
339 ftResult = FT_Load_Char( face, index, FT_LOAD_RENDER );
347 FT_Int glyph_advance = (face->glyph->advance.x >> 6 );
348 unsigned char* buffer = face->glyph->bitmap.buffer;
350 if (
nullptr == buffer)
357 int y_bearnig = max_bear - ( face->glyph->metrics.horiBearingY >> 6 );
360 if (
int(finalWidth - 1) < (len + face->glyph->bitmap.width + mDistance) ) { height += max_height + mDistance; len = mDistance; }
362 for (
int j = 0; j < face->glyph->bitmap.rows; j++ )
364 int row = j + (int)height + y_bearnig;
365 uint8* pDest = &imageData[(row * data_width) + (len + ( face->glyph->metrics.horiBearingX >> 6 )) * pixel_bytes];
366 for (
int k = 0; k < face->glyph->bitmap.width; k++ )
368 if (mAntialiasColour) pDest = writeData(pDest, *buffer, *buffer, rgbaMode);
374 addGlyph(&info, index, len, height, len + glyph_advance, height + max_height, finalWidth, finalHeight, textureAspect, mOffsetHeight);
375 len += (glyph_advance + mDistance);
388 mVectorRangeInfo.push_back(info);
394 memcpy(buffer_ptr, imageData, data_size);
400 FT_Done_FreeType(ftLibrary);
402 #endif // MYGUI_USE_FREETYPE
406 void ResourceTrueTypeFont::addCodePointRange(
Char _first,
Char _second)
408 mVectorRangeInfo.push_back(RangeInfo(_first, _second));
411 void ResourceTrueTypeFont::addHideCodePointRange(
Char _first,
Char _second)
413 mVectorHideCodePoint.push_back(PairCodePoint(_first, _second));
417 bool ResourceTrueTypeFont::checkHidePointCode(
Char _id)
419 for (VectorPairCodePoint::iterator iter=mVectorHideCodePoint.begin(); iter!=mVectorHideCodePoint.end(); ++iter)
421 if (iter->isExist(_id))
return true;
426 void ResourceTrueTypeFont::clearCodePointRanges()
428 mVectorRangeInfo.clear();
429 mVectorHideCodePoint.clear();
439 if (node->
getName() ==
"Property")
443 if (key ==
"Source") mSource = value;
453 else if (node->
getName() ==
"Codes")
456 while (range.
next(
"Code"))
458 std::string range_value;
459 std::vector<std::string> parse_range;
464 if (!parse_range.empty())
468 addCodePointRange(first, last);
475 if (!parse_range.empty())
479 addHideCodePointRange(first, last);