MyGUI: MyGUI_ResourceTrueTypeFont.cpp Source File

MyGUI 3.2.2

MyGUI_ResourceTrueTypeFont.cpp
Go to the documentation of this file.
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_ResourceTrueTypeFont.h"
9 #include "MyGUI_DataManager.h"
10 #include "MyGUI_DataStreamHolder.h"
11 #include "MyGUI_RenderManager.h"
12 #include "MyGUI_Bitwise.h"
13
14 #ifdef MYGUI_USE_FREETYPE
15
16 # include FT_GLYPH_H
17 # include FT_TRUETYPE_TABLES_H
18 # include FT_BITMAP_H
19 # include FT_WINFONTS_H
20
21 // The following macro enables a workaround for a bug in FreeType's bytecode interpreter that, when using certain fonts at
22 // certain sizes, causes FreeType to start measuring and rendering some glyphs inconsistently after certain other glyphs have
23 // been loaded. See FreeType bug #35374 for details: https://savannah.nongnu.org/bugs/?35374
24 //
25 // To reproduce the bug, first disable the workaround by defining MYGUI_USE_FREETYPE_BYTECODE_BUG_FIX to 0. Then load the
26 // DejaVu Sans font at 10 pt using default values for all other properties. Observe that the glyphs for the "0", 6", "8", and
27 // "9" characters are now badly corrupted when rendered.
28 //
29 // This bug still exists as of FreeType 2.4.8 and there are currently no plans to fix it. If the bug is ever fixed, this
30 // workaround should be disabled, as it causes fonts to take longer to load.
31 //
32 // The bug can currently also be suppressed by disabling FreeType's bytecode interpreter altogether. To do so, remove the
33 // TT_CONFIG_OPTION_BYTECODE_INTERPRETER macro in the "ftoption.h" FreeType header file. Once this is done, this workaround can
34 // be safely disabled. Note that disabling FreeType's bytecode interpreter will cause rendered text to look somewhat different.
35 // Whether it looks better or worse is a matter of taste and may also depend on the font.
36 # ifndef MYGUI_USE_FREETYPE_BYTECODE_BUG_FIX
37 # define MYGUI_USE_FREETYPE_BYTECODE_BUG_FIX 1
38 # endif
39
40 #endif // MYGUI_USE_FREETYPE
41
42 namespace MyGUI
43 {
44
45 #ifndef MYGUI_USE_FREETYPE
46 ResourceTrueTypeFont::ResourceTrueTypeFont()
47 {
48 }
49
50 ResourceTrueTypeFont::~ResourceTrueTypeFont()
51 {
52 }
53
54 void ResourceTrueTypeFont::deserialization(xml::ElementPtr _node, Version _version)
55 {
56 Base::deserialization(_node, _version);
57 MYGUI_LOG(Error, "ResourceTrueTypeFont: TrueType font '" << getResourceName() << "' disabled. Define MYGUI_USE_FREETYE if you need TrueType fonts.");
58 }
59
60 GlyphInfo* ResourceTrueTypeFont::getGlyphInfo(Char _id)
61 {
62 return nullptr;
63 }
64
65 ITexture* ResourceTrueTypeFont::getTextureFont()
66 {
67 return nullptr;
68 }
69
70 int ResourceTrueTypeFont::getDefaultHeight()
71 {
72 return 0;
73 }
74
75 std::vector<std::pair<Char, Char> > ResourceTrueTypeFont::getCodePointRanges() const
76 {
77 return std::vector<std::pair<Char, Char> >();
78 }
79
80 Char ResourceTrueTypeFont::getSubstituteCodePoint() const
81 {
82 return Char();
83 }
84
85 void ResourceTrueTypeFont::initialise()
86 {
87 }
88
89 void ResourceTrueTypeFont::setSource(const std::string& _value)
90 {
91 }
92
93 void ResourceTrueTypeFont::setSize(float _value)
94 {
95 }
96
97 void ResourceTrueTypeFont::setResolution(uint _value)
98 {
99 }
100
101 void ResourceTrueTypeFont::setHinting(const std::string& _value)
102 {
103 }
104
105 void ResourceTrueTypeFont::setAntialias(bool _value)
106 {
107 }
108
109 void ResourceTrueTypeFont::setTabWidth(float _value)
110 {
111 }
112
113 void ResourceTrueTypeFont::setOffsetHeight(int _value)
114 {
115 }
116
117 void ResourceTrueTypeFont::setSubstituteCode(int _value)
118 {
119 }
120
121 void ResourceTrueTypeFont::setDistance(int _value)
122 {
123 }
124
125 void ResourceTrueTypeFont::addCodePointRange(Char _first, Char _second)
126 {
127 }
128
129 void ResourceTrueTypeFont::removeCodePointRange(Char _first, Char _second)
130 {
131 }
132
133 #else // MYGUI_USE_FREETYPE
134 namespace
135 {
136
137 template<typename T>
138 void setMax(T& _var, const T& _newValue)
139 {
140 if (_var < _newValue)
141 _var = _newValue;
142 }
143
144 std::pair<const Char, const uint8> charMaskData[] =
145 {
146 std::make_pair(FontCodeType::Selected, (const uint8)'\x88'),
147 std::make_pair(FontCodeType::SelectedBack, (const uint8)'\x60'),
148 std::make_pair(FontCodeType::Cursor, (const uint8)'\xFF'),
149 std::make_pair(FontCodeType::Tab, (const uint8)'\x00')
150 };
151
152 const std::map<const Char, const uint8> charMask(charMaskData, charMaskData + sizeof charMaskData / sizeof(*charMaskData));
153
154 const uint8 charMaskBlack = (const uint8)'\x00';
155 const uint8 charMaskWhite = (const uint8)'\xFF';
156
157 template<bool LAMode>
158 struct PixelBase
159 {
160 // Returns PixelFormat::R8G8B8A8 when LAMode is false, or PixelFormat::L8A8 when LAMode is true.
161 static PixelFormat::Enum getFormat();
162
163 // Returns 4 when LAMode is false, or 2 when LAMode is true.
164 static size_t getNumBytes();
165
166 protected:
167 // Sets a pixel in _dest as 4 or 2 bytes: L8L8L8A8 if LAMode is false, or L8A8 if LAMode is true.
168 // Automatically advances _dest just past the pixel written.
169 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha);
170 };
171
172 template<>
173 struct PixelBase<false>
174 {
175 static size_t getNumBytes()
176 {
177 return 4;
178 }
179
180 static PixelFormat::Enum getFormat()
181 {
182 return PixelFormat::R8G8B8A8;
183 }
184
185 protected:
186 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha)
187 {
188 *_dest++ = _luminance;
189 *_dest++ = _luminance;
190 *_dest++ = _luminance;
191 *_dest++ = _alpha;
192 }
193 };
194
195 template<>
196 struct PixelBase<true>
197 {
198 static size_t getNumBytes()
199 {
200 return 2;
201 }
202
203 static PixelFormat::Enum getFormat()
204 {
205 return PixelFormat::L8A8;
206 }
207
208 protected:
209 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha)
210 {
211 *_dest++ = _luminance;
212 *_dest++ = _alpha;
213 }
214 };
215
216 template<bool LAMode, bool FromSource = false, bool Antialias = false>
217 struct Pixel : PixelBase<LAMode>
218 {
219 // Sets a pixel in _dest as 4 or 2 bytes: L8L8L8A8 if LAMode is false, or L8A8 if LAMode is true.
220 // Sets luminance from _source if both FromSource and Antialias are true; otherwise, uses the specified value.
221 // Sets alpha from _source if FromSource is true; otherwise, uses the specified value.
222 // Automatically advances _source just past the pixel read if FromSource is true.
223 // Automatically advances _dest just past the pixel written.
224 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha, uint8*& _source);
225 };
226
227 template<bool LAMode, bool Antialias>
228 struct Pixel<LAMode, false, Antialias> : PixelBase<LAMode>
229 {
230 // Sets the destination pixel using the specified luminance and alpha. Source is ignored, since FromSource is false.
231 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha, uint8* = nullptr)
232 {
233 PixelBase<LAMode>::set(_dest, _luminance, _alpha);
234 }
235 };
236
237 template<bool LAMode>
238 struct Pixel<LAMode, true, false> : PixelBase<LAMode>
239 {
240 // Sets the destination pixel using the specified _luminance and using the alpha from the specified source.
241 static void set(uint8*& _dest, uint8 _luminance, uint8, uint8*& _source)
242 {
243 PixelBase<LAMode>::set(_dest, _luminance, *_source++);
244 }
245 };
246
247 template<bool LAMode>
248 struct Pixel<LAMode, true, true> : PixelBase<LAMode>
249 {
250 // Sets the destination pixel using both the luminance and alpha from the specified source, since Antialias is true.
251 static void set(uint8*& _dest, uint8, uint8, uint8*& _source)
252 {
253 PixelBase<LAMode>::set(_dest, *_source, *_source);
254 ++_source;
255 }
256 };
257
258 }
259
260 const int ResourceTrueTypeFont::mDefaultGlyphSpacing = 1;
261 const float ResourceTrueTypeFont::mDefaultTabWidth = 8.0f;
262 const float ResourceTrueTypeFont::mSelectedWidth = 1.0f;
263 const float ResourceTrueTypeFont::mCursorWidth = 2.0f;
264
265 ResourceTrueTypeFont::ResourceTrueTypeFont() :
266 mSize(0),
267 mResolution(96),
268 mHinting(HintingUseNative),
269 mAntialias(false),
270 mSpaceWidth(0.0f),
271 mGlyphSpacing(-1),
272 mTabWidth(0.0f),
273 mOffsetHeight(0),
274 mSubstituteCodePoint(static_cast<Char>(FontCodeType::NotDefined)),
275 mDefaultHeight(0),
276 mSubstituteGlyphInfo(nullptr),
277 mTexture(nullptr)
278 {
279 }
280
281 ResourceTrueTypeFont::~ResourceTrueTypeFont()
282 {
283 if (mTexture != nullptr)
284 {
285 RenderManager::getInstance().destroyTexture(mTexture);
286 mTexture = nullptr;
287 }
288 }
289
290 void ResourceTrueTypeFont::deserialization(xml::ElementPtr _node, Version _version)
291 {
292 Base::deserialization(_node, _version);
293
294 xml::ElementEnumerator node = _node->getElementEnumerator();
295 while (node.next())
296 {
297 if (node->getName() == "Property")
298 {
299 const std::string& key = node->findAttribute("key");
300 const std::string& value = node->findAttribute("value");
301 if (key == "Source")
302 setSource(value);
303 else if (key == "Size")
304 setSize(utility::parseFloat(value));
305 else if (key == "Resolution")
306 setResolution(utility::parseUInt(value));
307 else if (key == "Antialias")
308 setAntialias(utility::parseBool(value));
309 else if (key == "TabWidth")
310 setTabWidth(utility::parseFloat(value));
311 else if (key == "OffsetHeight")
312 setOffsetHeight(utility::parseInt(value));
313 else if (key == "SubstituteCode")
314 setSubstituteCode(utility::parseInt(value));
315 else if (key == "Distance")
316 setDistance(utility::parseInt(value));
317 else if (key == "Hinting")
318 setHinting(value);
319 else if (key == "SpaceWidth")
320 {
321 mSpaceWidth = utility::parseFloat(value);
322 MYGUI_LOG(Warning, _node->findAttribute("type") << ": Property '" << key << "' in font '" << _node->findAttribute("name") << "' is deprecated; remove it to use automatic calculation.");
323 }
324 else if (key == "CursorWidth")
325 {
326 MYGUI_LOG(Warning, _node->findAttribute("type") << ": Property '" << key << "' in font '" << _node->findAttribute("name") << "' is deprecated; value ignored.");
327 }
328 }
329 else if (node->getName() == "Codes")
330 {
331 // Range of inclusions.
332 xml::ElementEnumerator range = node->getElementEnumerator();
333 while (range.next("Code"))
334 {
335 std::string range_value;
336 if (range->findAttribute("range", range_value))
337 {
338 std::vector<std::string> parse_range = utility::split(range_value);
339 if (!parse_range.empty())
340 {
341 Char first = utility::parseUInt(parse_range[0]);
342 Char last = parse_range.size() > 1 ? utility::parseUInt(parse_range[1]) : first;
343 addCodePointRange(first, last);
344 }
345 }
346 }
347
348 // If no code points have been included, include the Unicode Basic Multilingual Plane by default before processing
349 // any exclusions.
350 if (mCharMap.empty())
351 addCodePointRange(0, 0xFFFF);
352
353 // Range of exclusions.
354 range = node->getElementEnumerator();
355 while (range.next("Code"))
356 {
357 std::string range_value;
358 if (range->findAttribute("hide", range_value))
359 {
360 std::vector<std::string> parse_range = utility::split(range_value);
361 if (!parse_range.empty())
362 {
363 Char first = utility::parseUInt(parse_range[0]);
364 Char last = parse_range.size() > 1 ? utility::parseUInt(parse_range[1]) : first;
365 removeCodePointRange(first, last);
366 }
367 }
368 }
369 }
370 }
371
372 initialise();
373 }
374
375 GlyphInfo* ResourceTrueTypeFont::getGlyphInfo(Char _id)
376 {
377 CharMap::const_iterator charIter = mCharMap.find(_id);
378
379 if (charIter != mCharMap.end())
380 {
381 GlyphMap::iterator glyphIter = mGlyphMap.find(charIter->second);
382
383 if (glyphIter != mGlyphMap.end())
384 return &glyphIter->second;
385 }
386
387 return mSubstituteGlyphInfo;
388 }
389
390 ITexture* ResourceTrueTypeFont::getTextureFont()
391 {
392 return mTexture;
393 }
394
395 int ResourceTrueTypeFont::getDefaultHeight()
396 {
397 return mDefaultHeight;
398 }
399
400 std::vector<std::pair<Char, Char> > ResourceTrueTypeFont::getCodePointRanges() const
401 {
402 std::vector<std::pair<Char, Char> > result;
403
404 if (!mCharMap.empty())
405 {
406 CharMap::const_iterator iter = mCharMap.begin(), endIter = mCharMap.end();
407
408 // Start the first range with the first code point in the map.
409 Char rangeBegin = iter->first, rangeEnd = rangeBegin;
410
411 // Loop over the rest of the map and find the contiguous ranges.
412 for (++iter; iter != endIter; ++iter)
413 {
414 if (iter->first == rangeEnd + 1)
415 {
416 // Extend the current range.
417 ++rangeEnd;
418 }
419 else
420 {
421 // Found the start of a new range. First, save the current range.
422 result.push_back(std::make_pair(rangeBegin, rangeEnd));
423
424 // Then start the new range.
425 rangeBegin = rangeEnd = iter->first;
426 }
427 }
428
429 // Save the final range.
430 result.push_back(std::make_pair(rangeBegin, rangeEnd));
431 }
432
433 return result;
434 }
435
436 Char ResourceTrueTypeFont::getSubstituteCodePoint() const
437 {
438 return mSubstituteCodePoint;
439 }
440
441 void ResourceTrueTypeFont::addCodePoint(Char _codePoint)
442 {
443 mCharMap.insert(CharMap::value_type(_codePoint, 0));
444 }
445
446 void ResourceTrueTypeFont::removeCodePoint(Char _codePoint)
447 {
448 mCharMap.erase(_codePoint);
449 }
450
451 void ResourceTrueTypeFont::addCodePointRange(Char _first, Char _second)
452 {
453 CharMap::iterator positionHint = mCharMap.lower_bound(_first);
454
455 if (positionHint != mCharMap.begin())
456 --positionHint;
457
458 for (Char i = _first; i <= _second; ++i)
459 positionHint = mCharMap.insert(positionHint, CharMap::value_type(i, 0));
460 }
461
462 void ResourceTrueTypeFont::removeCodePointRange(Char _first, Char _second)
463 {
464 mCharMap.erase(mCharMap.lower_bound(_first), mCharMap.upper_bound(_second));
465 }
466
467 void ResourceTrueTypeFont::clearCodePoints()
468 {
469 mCharMap.clear();
470 }
471
472 void ResourceTrueTypeFont::initialise()
473 {
474 if (mGlyphSpacing == -1)
475 mGlyphSpacing = mDefaultGlyphSpacing;
476
477 // If L8A8 (2 bytes per pixel) is supported, use it; otherwise, use R8G8B8A8 (4 bytes per pixel) as L8L8L8A8.
478 bool laMode = MyGUI::RenderManager::getInstance().isFormatSupported(Pixel<true>::getFormat(), TextureUsage::Static | TextureUsage::Write);
479
480 // Select and call an appropriate initialisation method. By making this decision up front, we avoid having to branch on
481 // these variables many thousands of times inside tight nested loops later. From this point on, the various function
482 // templates ensure that all of the necessary branching is done purely at compile time for all combinations.
483 int init = (laMode ? 2 : 0) | (mAntialias ? 1 : 0);
484
485 switch (init)
486 {
487 case 0:
488 ResourceTrueTypeFont::initialiseFreeType<false, false>();
489 break;
490 case 1:
491 ResourceTrueTypeFont::initialiseFreeType<false, true>();
492 break;
493 case 2:
494 ResourceTrueTypeFont::initialiseFreeType<true, false>();
495 break;
496 case 3:
497 ResourceTrueTypeFont::initialiseFreeType<true, true>();
498 break;
499 }
500 }
501
502 template<bool LAMode, bool Antialias>
503 void ResourceTrueTypeFont::initialiseFreeType()
504 {
505 //-------------------------------------------------------------------//
506 // Initialise FreeType and load the font.
507 //-------------------------------------------------------------------//
508
509 FT_Library ftLibrary;
510
511 if (FT_Init_FreeType(&ftLibrary) != 0)
512 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not init the FreeType library!");
513
514 uint8* fontBuffer = nullptr;
515
516 FT_Face ftFace = loadFace(ftLibrary, fontBuffer);
517
518 if (ftFace == nullptr)
519 {
520 MYGUI_LOG(Error, "ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
521 return;
522 }
523
524 //-------------------------------------------------------------------//
525 // Calculate the font metrics.
526 //-------------------------------------------------------------------//
527
528 // The font's overall ascent and descent are defined in three different places in a TrueType font, and with different
529 // values in each place. The most reliable source for these metrics is usually the "usWinAscent" and "usWinDescent" pair of
530 // values in the OS/2 header; however, some fonts contain inaccurate data there. To be safe, we use the highest of the set
531 // of values contained in the face metrics and the two sets of values contained in the OS/2 header.
532 int fontAscent = ftFace->size->metrics.ascender >> 6;
533 int fontDescent = -ftFace->size->metrics.descender >> 6;
534
535 TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(ftFace, ft_sfnt_os2);
536
537 if (os2 != nullptr)
538 {
539 setMax(fontAscent, os2->usWinAscent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
540 setMax(fontDescent, os2->usWinDescent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
541
542 setMax(fontAscent, os2->sTypoAscender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
543 setMax(fontDescent, -os2->sTypoDescender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
544 }
545
546 // The nominal font height is calculated as the sum of its ascent and descent as specified by the font designer. Previously
547 // it was defined by MyGUI in terms of the maximum ascent and descent of the glyphs currently in use, but this caused the
548 // font's line spacing to change whenever glyphs were added to or removed from the font definition. Doing it this way
549 // instead prevents a lot of layout problems, and it is also more typographically correct and more aesthetically pleasing.
550 mDefaultHeight = fontAscent + fontDescent;
551
552 // Set the load flags based on the specified type of hinting.
553 FT_Int32 ftLoadFlags;
554
555 switch (mHinting)
556 {
557 case HintingForceAuto:
558 ftLoadFlags = FT_LOAD_FORCE_AUTOHINT;
559 break;
560 case HintingDisableAuto:
561 ftLoadFlags = FT_LOAD_NO_AUTOHINT;
562 break;
563 case HintingDisableAll:
564 // When hinting is completely disabled, glyphs must always be rendered -- even during layout calculations -- due to
565 // discrepancies between the glyph metrics and the actual rendered bitmap metrics.
566 ftLoadFlags = FT_LOAD_NO_HINTING | FT_LOAD_RENDER;
567 break;
568 //case HintingUseNative:
569 default:
570 ftLoadFlags = FT_LOAD_DEFAULT;
571 break;
572 }
573
574 //-------------------------------------------------------------------//
575 // Create the glyphs and calculate their metrics.
576 //-------------------------------------------------------------------//
577
578 GlyphHeightMap glyphHeightMap;
579 int texWidth = 0;
580
581 // Before creating the glyphs, add the "Space" code point to force that glyph to be created. For historical reasons, MyGUI
582 // users are accustomed to omitting this code point in their font definitions.
583 addCodePoint(FontCodeType::Space);
584
585 // Create the standard glyphs.
586 for (CharMap::iterator iter = mCharMap.begin(); iter != mCharMap.end(); )
587 {
588 const Char& codePoint = iter->first;
589 FT_UInt glyphIndex = FT_Get_Char_Index(ftFace, codePoint);
590
591 texWidth += createFaceGlyph(glyphIndex, codePoint, fontAscent, ftFace, ftLoadFlags, glyphHeightMap);
592
593 // If the newly created glyph is the "Not Defined" glyph, it means that the code point is not supported by the font.
594 // Remove it from the character map so that we can provide our own substitute instead of letting FreeType do it.
595 if (iter->second != 0)
596 ++iter;
597 else
598 mCharMap.erase(iter++);
599 }
600
601 #if MYGUI_USE_FREETYPE_BYTECODE_BUG_FIX
602
603 bool isBytecodeAvailable = (ftFace->face_flags & FT_FACE_FLAG_HINTER) != 0;
604 bool isBytecodeUsedByLoadFlags = (ftLoadFlags & (FT_LOAD_FORCE_AUTOHINT | FT_LOAD_NO_HINTING)) == 0;
605
606 if (isBytecodeAvailable && isBytecodeUsedByLoadFlags)
607 {
608 for (GlyphMap::iterator iter = mGlyphMap.begin(); iter != mGlyphMap.end(); ++iter)
609 {
610 if (FT_Load_Glyph(ftFace, iter->first, ftLoadFlags) == 0)
611 {
612 GlyphInfo& info = iter->second;
613 GlyphInfo newInfo = createFaceGlyphInfo(0, fontAscent, ftFace->glyph);
614
615 if (info.width != newInfo.width)
616 {
617 texWidth += (int)ceil(newInfo.width) - (int)ceil(info.width);
618 info.width = newInfo.width;
619 }
620
621 if (info.height != newInfo.height)
622 {
623 GlyphHeightMap::mapped_type oldHeightMap = glyphHeightMap[(FT_Pos)info.height];
624 GlyphHeightMap::mapped_type::iterator heightMapItem = oldHeightMap.find(iter->first);
625 glyphHeightMap[(FT_Pos)newInfo.height].insert(*heightMapItem);
626 oldHeightMap.erase(heightMapItem);
627 info.height = newInfo.height;
628 }
629
630 if (info.advance != newInfo.advance)
631 info.advance = newInfo.advance;
632
633 if (info.bearingX != newInfo.bearingX)
634 info.bearingX = newInfo.bearingX;
635
636 if (info.bearingY != newInfo.bearingY)
637 info.bearingY = newInfo.bearingY;
638 }
639 else
640 {
641 MYGUI_LOG(Warning, "ResourceTrueTypeFont: Cannot load glyph " << iter->first << " for character " << iter->second.codePoint << " in font '" << getResourceName() << "'.");
642 }
643 }
644 }
645
646 #endif // MYGUI_USE_FREETYPE_BYTECODE_BUG_FIX
647
648 // Do some special handling for the "Space" and "Tab" glyphs.
649 GlyphInfo* spaceGlyphInfo = getGlyphInfo(FontCodeType::Space);
650
651 if (spaceGlyphInfo != nullptr && spaceGlyphInfo->codePoint == FontCodeType::Space)
652 {
653 // Adjust the width of the "Space" glyph if it has been customized.
654 if (mSpaceWidth != 0.0f)
655 {
656 texWidth += (int)ceil(mSpaceWidth) - (int)ceil(spaceGlyphInfo->width);
657 spaceGlyphInfo->width = mSpaceWidth;
658 spaceGlyphInfo->advance = mSpaceWidth;
659 }
660
661 // If the width of the "Tab" glyph hasn't been customized, make it eight spaces wide.
662 if (mTabWidth == 0.0f)
663 mTabWidth = mDefaultTabWidth * spaceGlyphInfo->advance;
664 }
665
666 // Create the special glyphs. They must be created after the standard glyphs so that they take precedence in case of a
667 // collision. To make sure that the indices of the special glyphs don't collide with any glyph indices in the font, we must
668 // use glyph indices higher than the highest glyph index in the font.
669 FT_UInt nextGlyphIndex = (FT_UInt)ftFace->num_glyphs;
670
671 float height = (float)mDefaultHeight;
672
673 texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Tab), 0.0f, 0.0f, mTabWidth, 0.0f, 0.0f), glyphHeightMap);
674 texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Selected), mSelectedWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap);
675 texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::SelectedBack), mSelectedWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap);
676 texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Cursor), mCursorWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap);
677
678 // If a substitute code point has been specified, check to make sure that it exists in the character map. If it doesn't,
679 // revert to the default "Not Defined" code point. This is not a real code point but rather an invalid Unicode value that
680 // is guaranteed to cause the "Not Defined" special glyph to be created.
681 if (mSubstituteCodePoint != FontCodeType::NotDefined && mCharMap.find(mSubstituteCodePoint) == mCharMap.end())
682 mSubstituteCodePoint = static_cast<Char>(FontCodeType::NotDefined);
683
684 // Create the "Not Defined" code point (and its corresponding glyph) if it's in use as the substitute code point.
685 if (mSubstituteCodePoint == FontCodeType::NotDefined)
686 texWidth += createFaceGlyph(0, static_cast<Char>(FontCodeType::NotDefined), fontAscent, ftFace, ftLoadFlags, glyphHeightMap);
687
688 // Cache a pointer to the substitute glyph info for fast lookup.
689 mSubstituteGlyphInfo = &mGlyphMap.find(mCharMap.find(mSubstituteCodePoint)->second)->second;
690
691 // Calculate the average height of all of the glyphs that are in use. This value will be used for estimating how large the
692 // texture needs to be.
693 double averageGlyphHeight = 0.0;
694
695 for (GlyphHeightMap::const_iterator j = glyphHeightMap.begin(); j != glyphHeightMap.end(); ++j)
696 averageGlyphHeight += j->first * j->second.size();
697
698 averageGlyphHeight /= mGlyphMap.size();
699
700 //-------------------------------------------------------------------//
701 // Calculate the final texture size.
702 //-------------------------------------------------------------------//
703
704 // Round the current texture width and height up to the nearest powers of two.
705 texWidth = Bitwise::firstPO2From(texWidth);
706 int texHeight = Bitwise::firstPO2From((int)ceil(averageGlyphHeight) + mGlyphSpacing);
707
708 // At this point, the texture is only one glyph high and is probably very wide. For efficiency reasons, we need to make the
709 // texture as square as possible. If the texture cannot be made perfectly square, make it taller than it is wide, because
710 // the height may decrease in the final layout due to height packing.
711 while (texWidth > texHeight)
712 {
713 texWidth /= 2;
714 texHeight *= 2;
715 }
716
717 // Calculate the final layout of all of the glyphs in the texture, packing them tightly by first arranging them by height.
718 // We assume that the texture width is fixed but that the texture height can be adjusted up or down depending on how much
719 // space is actually needed.
720 // In most cases, the final texture will end up square or almost square. In some rare cases, however, we can end up with a
721 // texture that's more than twice as high as it is wide; when this happens, we double the width and try again.
722 do
723 {
724 if (texHeight > texWidth * 2)
725 texWidth *= 2;
726
727 int texX = 0, texY = 0;
728
729 for (GlyphHeightMap::const_iterator j = glyphHeightMap.begin(); j != glyphHeightMap.end(); ++j)
730 {
731 for (GlyphHeightMap::mapped_type::const_iterator i = j->second.begin(); i != j->second.end(); ++i)
732 {
733 GlyphInfo& info = *i->second;
734
735 int glyphWidth = (int)ceil(info.width);
736 int glyphHeight = (int)ceil(info.height);
737
738 autoWrapGlyphPos(glyphWidth, texWidth, glyphHeight, texX, texY);
739
740 if (glyphWidth > 0)
741 texX += mGlyphSpacing + glyphWidth;
742 }
743 }
744
745 texHeight = Bitwise::firstPO2From(texY + glyphHeightMap.rbegin()->first);
746 }
747 while (texHeight > texWidth * 2);
748
749 //-------------------------------------------------------------------//
750 // Create the texture and render the glyphs onto it.
751 //-------------------------------------------------------------------//
752
753 mTexture = RenderManager::getInstance().createTexture(MyGUI::utility::toString((size_t)this, "_TrueTypeFont"));
754
755 mTexture->createManual(texWidth, texHeight, TextureUsage::Static | TextureUsage::Write, Pixel<LAMode>::getFormat());
756
757 uint8* texBuffer = static_cast<uint8*>(mTexture->lock(TextureUsage::Write));
758
759 if (texBuffer != nullptr)
760 {
761 // Make the texture background transparent white.
762 for (uint8* dest = texBuffer, * endDest = dest + texWidth * texHeight * Pixel<LAMode>::getNumBytes(); dest != endDest; )
763 Pixel<LAMode, false, false>::set(dest, charMaskWhite, charMaskBlack);
764
765 renderGlyphs<LAMode, Antialias>(glyphHeightMap, ftLibrary, ftFace, ftLoadFlags, texBuffer, texWidth, texHeight);
766
767 mTexture->unlock();
768
769 MYGUI_LOG(Info, "ResourceTrueTypeFont: Font '" << getResourceName() << "' using texture size " << texWidth << " x " << texHeight << ".");
770 MYGUI_LOG(Info, "ResourceTrueTypeFont: Font '" << getResourceName() << "' using real height " << mDefaultHeight << " pixels.");
771 }
772 else
773 {
774 MYGUI_LOG(Error, "ResourceTrueTypeFont: Error locking texture; pointer is nullptr.");
775 }
776
777 FT_Done_Face(ftFace);
778 FT_Done_FreeType(ftLibrary);
779
780 delete [] fontBuffer;
781 }
782
783 FT_Face ResourceTrueTypeFont::loadFace(const FT_Library& _ftLibrary, uint8*& _fontBuffer)
784 {
785 FT_Face result = nullptr;
786
787 // Load the font file.
788 IDataStream* datastream = DataManager::getInstance().getData(mSource);
789
790 if (datastream == nullptr)
791 return result;
792
793 size_t fontBufferSize = datastream->size();
794 _fontBuffer = new uint8[fontBufferSize];
795 datastream->read(_fontBuffer, fontBufferSize);
796
797 DataManager::getInstance().freeData(datastream);
798 datastream = nullptr;
799
800 // Determine how many faces the font contains.
801 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, -1, &result) != 0)
802 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
803
804 FT_Long numFaces = result->num_faces;
805 FT_Long faceIndex = 0;
806
807 // Load the first face.
808 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
809 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
810
811 if (result->face_flags & FT_FACE_FLAG_SCALABLE)
812 {
813 // The font is scalable, so set the font size by first converting the requested size to FreeType's 26.6 fixed-point
814 // format.
815 FT_F26Dot6 ftSize = (FT_F26Dot6)(mSize * (1 << 6));
816
817 if (FT_Set_Char_Size(result, ftSize, 0, mResolution, mResolution) != 0)
818 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!");
819
820 // If no code points have been specified, use the Unicode Basic Multilingual Plane by default.
821 if (mCharMap.empty())
822 addCodePointRange(0, 0xFFFF);
823 }
824 else
825 {
826 // The font isn't scalable, so try to load it as a Windows FNT/FON file.
827 FT_WinFNT_HeaderRec fnt;
828
829 // Enumerate all of the faces in the font and select the smallest one that's at least as large as the requested size
830 // (after adjusting for resolution). If none of the faces are large enough, use the largest one.
831 std::map<float, FT_Long> faceSizes;
832
833 do
834 {
835 if (FT_Get_WinFNT_Header(result, &fnt) != 0)
836 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
837
838 faceSizes.insert(std::make_pair((float)fnt.nominal_point_size * fnt.vertical_resolution / mResolution, faceIndex));
839
840 FT_Done_Face(result);
841
842 if (++faceIndex < numFaces)
843 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
844 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
845 }
846 while (faceIndex < numFaces);
847
848 std::map<float, FT_Long>::const_iterator iter = faceSizes.lower_bound(mSize);
849
850 faceIndex = (iter != faceSizes.end()) ? iter->second : faceSizes.rbegin()->second;
851
852 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
853 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
854
855 // Select the first bitmap strike available in the selected face. This needs to be done explicitly even though Windows
856 // FNT/FON files contain only one bitmap strike per face.
857 if (FT_Select_Size(result, 0) != 0)
858 MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!");
859
860 // Windows FNT/FON files do not support Unicode, so restrict the code-point range to either ISO-8859-1 or ASCII,
861 // depending on the font's encoding.
862 if (mCharMap.empty())
863 {
864 // No code points have been specified, so add the printable ASCII range by default.
865 addCodePointRange(0x20, 0x7E);
866
867 // Additionally, if the font's character set is CP-1252, add the range of non-ASCII 8-bit code points that are
868 // common between CP-1252 and ISO-8859-1; i.e., everything but 0x80 through 0x9F.
869 if (fnt.charset == FT_WinFNT_ID_CP1252)
870 addCodePointRange(0xA0, 0xFF);
871 }
872 else
873 {
874 // Some code points have been specified, so remove anything in the non-printable ASCII range as well as anything
875 // over 8 bits.
876 removeCodePointRange(0, 0x1F);
877 removeCodePointRange(0x100, std::numeric_limits<Char>::max());
878
879 // Additionally, remove non-ASCII 8-bit code points (plus ASCII DEL, 0x7F). If the font's character set is CP-1252,
880 // remove only the code points that differ between CP-1252 and ISO-8859-1; otherwise, remove all of them.
881 if (fnt.charset == FT_WinFNT_ID_CP1252)
882 removeCodePointRange(0x7F, 0x9F);
883 else
884 removeCodePointRange(0x7F, 0xFF);
885 }
886 }
887
888 return result;
889 }
890
891 void ResourceTrueTypeFont::autoWrapGlyphPos(int _glyphWidth, int _texWidth, int _lineHeight, int& _texX, int& _texY)
892 {
893 if (_glyphWidth > 0 && _texX + mGlyphSpacing + _glyphWidth > _texWidth)
894 {
895 _texX = 0;
896 _texY += mGlyphSpacing + _lineHeight;
897 }
898 }
899
900 GlyphInfo ResourceTrueTypeFont::createFaceGlyphInfo(Char _codePoint, int _fontAscent, FT_GlyphSlot _glyph)
901 {
902 float bearingX = _glyph->metrics.horiBearingX / 64.0f;
903
904 // The following calculations aren't currently needed but are kept here for future use.
905 // float ascent = _glyph->metrics.horiBearingY / 64.0f;
906 // float descent = (_glyph->metrics.height / 64.0f) - ascent;
907
908 return GlyphInfo(
909 _codePoint,
910 std::max((float)_glyph->bitmap.width, _glyph->metrics.width / 64.0f),
911 std::max((float)_glyph->bitmap.rows, _glyph->metrics.height / 64.0f),
912 (_glyph->advance.x / 64.0f) - bearingX,
913 bearingX,
914 floor(_fontAscent - (_glyph->metrics.horiBearingY / 64.0f) - mOffsetHeight));
915 }
916
917 int ResourceTrueTypeFont::createGlyph(FT_UInt _glyphIndex, const GlyphInfo& _glyphInfo, GlyphHeightMap& _glyphHeightMap)
918 {
919 int width = (int)ceil(_glyphInfo.width);
920 int height = (int)ceil(_glyphInfo.height);
921
922 mCharMap[_glyphInfo.codePoint] = _glyphIndex;
923 GlyphInfo& info = mGlyphMap.insert(GlyphMap::value_type(_glyphIndex, _glyphInfo)).first->second;
924 _glyphHeightMap[(FT_Pos)height].insert(std::make_pair(_glyphIndex, &info));
925
926 return (width > 0) ? mGlyphSpacing + width : 0;
927 }
928
929 int ResourceTrueTypeFont::createFaceGlyph(FT_UInt _glyphIndex, Char _codePoint, int _fontAscent, const FT_Face& _ftFace, FT_Int32 _ftLoadFlags, GlyphHeightMap& _glyphHeightMap)
930 {
931 if (mGlyphMap.find(_glyphIndex) == mGlyphMap.end())
932 {
933 if (FT_Load_Glyph(_ftFace, _glyphIndex, _ftLoadFlags) == 0)
934 return createGlyph(_glyphIndex, createFaceGlyphInfo(_codePoint, _fontAscent, _ftFace->glyph), _glyphHeightMap);
935 else
936 MYGUI_LOG(Warning, "ResourceTrueTypeFont: Cannot load glyph " << _glyphIndex << " for character " << _codePoint << " in font '" << getResourceName() << "'.");
937 }
938 else
939 {
940 mCharMap[_codePoint] = _glyphIndex;
941 }
942
943 return 0;
944 }
945
946 template<bool LAMode, bool Antialias>
947 void ResourceTrueTypeFont::renderGlyphs(const GlyphHeightMap& _glyphHeightMap, const FT_Library& _ftLibrary, const FT_Face& _ftFace, FT_Int32 _ftLoadFlags, uint8* _texBuffer, int _texWidth, int _texHeight)
948 {
949 FT_Bitmap ftBitmap;
950 FT_Bitmap_New(&ftBitmap);
951
952 int texX = 0, texY = 0;
953
954 for (GlyphHeightMap::const_iterator j = _glyphHeightMap.begin(); j != _glyphHeightMap.end(); ++j)
955 {
956 for (GlyphHeightMap::mapped_type::const_iterator i = j->second.begin(); i != j->second.end(); ++i)
957 {
958 GlyphInfo& info = *i->second;
959
960 switch (info.codePoint)
961 {
962 case FontCodeType::Selected:
963 case FontCodeType::SelectedBack:
964 {
965 renderGlyph<LAMode, false, false>(info, charMaskWhite, charMaskBlack, charMask.find(info.codePoint)->second, j->first, _texBuffer, _texWidth, _texHeight, texX, texY);
966
967 // Manually adjust the glyph's width to zero. This prevents artifacts from appearing at the seams when
968 // rendering multi-character selections.
969 GlyphInfo* glyphInfo = getGlyphInfo(info.codePoint);
970 glyphInfo->width = 0.0f;
971 glyphInfo->uvRect.right = glyphInfo->uvRect.left;
972 }
973 break;
974
975 case FontCodeType::Cursor:
976 case FontCodeType::Tab:
977 renderGlyph<LAMode, false, false>(info, charMaskWhite, charMaskBlack, charMask.find(info.codePoint)->second, j->first, _texBuffer, _texWidth, _texHeight, texX, texY);
978 break;
979
980 default:
981 if (FT_Load_Glyph(_ftFace, i->first, _ftLoadFlags | FT_LOAD_RENDER) == 0)
982 {
983 if (_ftFace->glyph->bitmap.buffer != nullptr)
984 {
985 uint8* glyphBuffer = nullptr;
986
987 switch (_ftFace->glyph->bitmap.pixel_mode)
988 {
989 case FT_PIXEL_MODE_GRAY:
990 glyphBuffer = _ftFace->glyph->bitmap.buffer;
991 break;
992
993 case FT_PIXEL_MODE_MONO:
994 // Convert the monochrome bitmap to 8-bit before rendering it.
995 if (FT_Bitmap_Convert(_ftLibrary, &_ftFace->glyph->bitmap, &ftBitmap, 1) == 0)
996 {
997 // Go through the bitmap and convert all of the nonzero values to 0xFF (white).
998 for (uint8* p = ftBitmap.buffer, * endP = p + ftBitmap.width * ftBitmap.rows; p != endP; ++p)
999 *p ^= -*p ^ *p;
1000
1001 glyphBuffer = ftBitmap.buffer;
1002 }
1003 break;
1004 }
1005
1006 if (glyphBuffer != nullptr)
1007 renderGlyph<LAMode, true, Antialias>(info, charMaskWhite, charMaskWhite, charMaskWhite, j->first, _texBuffer, _texWidth, _texHeight, texX, texY, glyphBuffer);
1008 }
1009 }
1010 else
1011 {
1012 MYGUI_LOG(Warning, "ResourceTrueTypeFont: Cannot render glyph " << i->first << " for character " << info.codePoint << " in font '" << getResourceName() << "'.");
1013 }
1014 break;
1015 }
1016 }
1017 }
1018
1019 FT_Bitmap_Done(_ftLibrary, &ftBitmap);
1020 }
1021
1022 template<bool LAMode, bool UseBuffer, bool Antialias>
1023 void ResourceTrueTypeFont::renderGlyph(GlyphInfo& _info, uint8 _luminance0, uint8 _luminance1, uint8 _alpha, int _lineHeight, uint8* _texBuffer, int _texWidth, int _texHeight, int& _texX, int& _texY, uint8* _glyphBuffer)
1024 {
1025 int width = (int)ceil(_info.width);
1026 int height = (int)ceil(_info.height);
1027
1028 autoWrapGlyphPos(width, _texWidth, _lineHeight, _texX, _texY);
1029
1030 uint8* dest = _texBuffer + (_texY * _texWidth + _texX) * Pixel<LAMode>::getNumBytes();
1031
1032 // Calculate how much to advance the destination pointer after each row to get to the start of the next row.
1033 ptrdiff_t destNextRow = (_texWidth - width) * Pixel<LAMode>::getNumBytes();
1034
1035 for (int j = height; j > 0; --j)
1036 {
1037 int i;
1038 for (i = width; i > 1; i -= 2)
1039 {
1040 Pixel<LAMode, UseBuffer, Antialias>::set(dest, _luminance0, _alpha, _glyphBuffer);
1041 Pixel<LAMode, UseBuffer, Antialias>::set(dest, _luminance1, _alpha, _glyphBuffer);
1042 }
1043
1044 if (i > 0)
1045 Pixel<LAMode, UseBuffer, Antialias>::set(dest, _luminance0, _alpha, _glyphBuffer);
1046
1047 dest += destNextRow;
1048 }
1049
1050 // Calculate and store the glyph's UV coordinates within the texture.
1051 _info.uvRect.left = (float)_texX / _texWidth; // u1
1052 _info.uvRect.top = (float)_texY / _texHeight; // v1
1053 _info.uvRect.right = (float)(_texX + _info.width) / _texWidth; // u2
1054 _info.uvRect.bottom = (float)(_texY + _info.height) / _texHeight; // v2
1055
1056 if (width > 0)
1057 _texX += mGlyphSpacing + width;
1058 }
1059
1060 void ResourceTrueTypeFont::setSource(const std::string& _value)
1061 {
1062 mSource = _value;
1063 }
1064
1065 void ResourceTrueTypeFont::setSize(float _value)
1066 {
1067 mSize = _value;
1068 }
1069
1070 void ResourceTrueTypeFont::setResolution(uint _value)
1071 {
1072 mResolution = _value;
1073 }
1074
1075 void ResourceTrueTypeFont::setHinting(const std::string& _value)
1076 {
1077 if (_value == "use_native")
1078 mHinting = HintingUseNative;
1079 else if (_value == "force_auto")
1080 mHinting = HintingForceAuto;
1081 else if (_value == "disable_auto")
1082 mHinting = HintingDisableAuto;
1083 else if (_value == "disable_all")
1084 mHinting = HintingDisableAll;
1085 else
1086 mHinting = HintingUseNative;
1087 }
1088
1089 void ResourceTrueTypeFont::setAntialias(bool _value)
1090 {
1091 mAntialias = _value;
1092 }
1093
1094 void ResourceTrueTypeFont::setTabWidth(float _value)
1095 {
1096 mTabWidth = _value;
1097 }
1098
1099 void ResourceTrueTypeFont::setOffsetHeight(int _value)
1100 {
1101 mOffsetHeight = _value;
1102 }
1103
1104 void ResourceTrueTypeFont::setSubstituteCode(int _value)
1105 {
1106 mSubstituteCodePoint = _value;
1107 }
1108
1109 void ResourceTrueTypeFont::setDistance(int _value)
1110 {
1111 mGlyphSpacing = _value;
1112 }
1113
1114 #endif // MYGUI_USE_FREETYPE
1115
1116 } // namespace MyGUI
MyGUI::Singleton< RenderManager >::getInstance
static RenderManager & getInstance()
Definition: MyGUI_Singleton.h:38
MyGUI_DataStreamHolder.h
MyGUI_DataManager.h
MyGUI::utility::toString
std::string toString(T p)
Definition: MyGUI_StringUtility.h:27
MyGUI::FontCodeType::Selected
Definition: MyGUI_FontData.h:29
MyGUI::PixelFormat::Enum
Enum
Definition: MyGUI_RenderFormat.h:51
MyGUI::ResourceTrueTypeFont::setHinting
void setHinting(const std::string &_value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:101
MyGUI::xml::ElementPtr
Element * ElementPtr
Definition: MyGUI_XmlDocument.h:104
MyGUI::utility::parseBool
bool parseBool(const std::string &_value)
Definition: MyGUI_StringUtility.h:191
MyGUI::TextureUsage::Write
Definition: MyGUI_RenderFormat.h:93
MyGUI::utility::parseUInt
unsigned int parseUInt(const std::string &_value)
Definition: MyGUI_StringUtility.h:171
MyGUI::ITexture::createManual
virtual void createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format)=0
MyGUI::FontCodeType::SelectedBack
Definition: MyGUI_FontData.h:30
MyGUI::ResourceTrueTypeFont::~ResourceTrueTypeFont
virtual ~ResourceTrueTypeFont()
Definition: MyGUI_ResourceTrueTypeFont.cpp:50
MyGUI::FontCodeType::Tab
Definition: MyGUI_FontData.h:20
MyGUI_ResourceTrueTypeFont.h
MyGUI::ResourceTrueTypeFont::getGlyphInfo
virtual GlyphInfo * getGlyphInfo(Char _id)
Definition: MyGUI_ResourceTrueTypeFont.cpp:60
MyGUI::FontCodeType::NotDefined
Definition: MyGUI_FontData.h:32
MyGUI::ResourceTrueTypeFont::addCodePointRange
void addCodePointRange(Char _first, Char _second)
Definition: MyGUI_ResourceTrueTypeFont.cpp:125
MyGUI::ResourceTrueTypeFont::getCodePointRanges
std::vector< std::pair< Char, Char > > getCodePointRanges() const
Definition: MyGUI_ResourceTrueTypeFont.cpp:75
MyGUI::IDataStream::size
virtual size_t size()=0
MyGUI::TextureUsage::Static
Definition: MyGUI_RenderFormat.h:89
MyGUI::ResourceTrueTypeFont::getDefaultHeight
virtual int getDefaultHeight()
Definition: MyGUI_ResourceTrueTypeFont.cpp:70
MyGUI::RenderManager::createTexture
virtual ITexture * createTexture(const std::string &_name)=0
MyGUI::ResourceTrueTypeFont::setOffsetHeight
void setOffsetHeight(int _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:113
MyGUI::xml::Element
Definition: MyGUI_XmlDocument.h:158
MyGUI::utility::parseFloat
float parseFloat(const std::string &_value)
Definition: MyGUI_StringUtility.h:181
MyGUI::DataManager::freeData
virtual void freeData(IDataStream *_data)=0
MyGUI::IResource::getResourceName
const std::string & getResourceName() const
Definition: MyGUI_IResource.h:32
MyGUI_Precompiled.h
MyGUI::RenderManager::destroyTexture
virtual void destroyTexture(ITexture *_texture)=0
MyGUI::PixelFormat::L8A8
Definition: MyGUI_RenderFormat.h:55
MyGUI::GlyphInfo
Definition: MyGUI_FontData.h:38
MyGUI::uint
unsigned int uint
Definition: MyGUI_Types.h:49
MyGUI::ResourceTrueTypeFont::setDistance
void setDistance(int _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:121
MyGUI::Version
Definition: MyGUI_Version.h:17
MYGUI_EXCEPT
#define MYGUI_EXCEPT(dest)
Definition: MyGUI_Diagnostic.h:33
MyGUI::PixelFormat::R8G8B8A8
Definition: MyGUI_RenderFormat.h:57
MyGUI::FontCodeType::Space
Definition: MyGUI_FontData.h:23
MyGUI::ResourceTrueTypeFont::setSubstituteCode
void setSubstituteCode(int _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:117
MyGUI::FontCodeType::Cursor
Definition: MyGUI_FontData.h:31
MyGUI::ResourceTrueTypeFont::ResourceTrueTypeFont
ResourceTrueTypeFont()
Definition: MyGUI_ResourceTrueTypeFont.cpp:46
MyGUI::ResourceTrueTypeFont::setSource
void setSource(const std::string &_value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:89
MyGUI::uint8
unsigned char uint8
Definition: MyGUI_Types.h:46
MyGUI::ResourceTrueTypeFont::deserialization
virtual void deserialization(xml::ElementPtr _node, Version _version)
Definition: MyGUI_ResourceTrueTypeFont.cpp:54
MYGUI_LOG
#define MYGUI_LOG(level, text)
Definition: MyGUI_Diagnostic.h:22
MyGUI::ResourceTrueTypeFont::setResolution
void setResolution(uint _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:97
nullptr
#define nullptr
Definition: MyGUI_Prerequest.h:29
MyGUI::utility::parseInt
int parseInt(const std::string &_value)
Definition: MyGUI_StringUtility.h:166
MyGUI::ITexture
Definition: MyGUI_ITexture.h:26
MyGUI::ResourceTrueTypeFont::setAntialias
void setAntialias(bool _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:105
MyGUI::Bitwise::firstPO2From
static __inline Type firstPO2From(Type _value)
Definition: MyGUI_Bitwise.h:21
MyGUI::ResourceTrueTypeFont::setSize
void setSize(float _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:93
MyGUI_RenderManager.h
MyGUI::Char
unsigned int Char
Definition: MyGUI_Types.h:51
MyGUI::ResourceTrueTypeFont::setTabWidth
void setTabWidth(float _value)
Definition: MyGUI_ResourceTrueTypeFont.cpp:109
MyGUI::ResourceTrueTypeFont::initialise
void initialise()
Definition: MyGUI_ResourceTrueTypeFont.cpp:85
MyGUI::IResource::deserialization
virtual void deserialization(xml::ElementPtr _node, Version _version)
Definition: MyGUI_IResource.h:51
MyGUI::ResourceTrueTypeFont::getTextureFont
virtual ITexture * getTextureFont()
Definition: MyGUI_ResourceTrueTypeFont.cpp:65
MyGUI
Definition: MyGUI_ActionController.h:14
MyGUI::ResourceTrueTypeFont::removeCodePointRange
void removeCodePointRange(Char _first, Char _second)
Definition: MyGUI_ResourceTrueTypeFont.cpp:129
MyGUI::RenderManager::isFormatSupported
virtual bool isFormatSupported(PixelFormat _format, TextureUsage _usage)
Definition: MyGUI_RenderManager.cpp:18
MyGUI::DataManager::getData
virtual IDataStream * getData(const std::string &_name)=0
MyGUI::utility::split
std::vector< std::string > split(const std::string &_source, const std::string &_delims="\t\n ")
Definition: MyGUI_StringUtility.h:291
MyGUI_Bitwise.h
MyGUI::ResourceTrueTypeFont::getSubstituteCodePoint
Char getSubstituteCodePoint() const
Definition: MyGUI_ResourceTrueTypeFont.cpp:80