14#ifdef MYGUI_USE_FREETYPE
17 #include FT_TRUETYPE_TABLES_H
19 #include FT_WINFONTS_H
21 #ifdef MYGUI_MSDF_FONTS
22 #include "msdfgen/msdfgen.h"
23 #include "msdfgen/msdfgen-ext.h"
31#ifndef MYGUI_USE_FREETYPE
32 ResourceTrueTypeFont::ResourceTrueTypeFont()
45 "ResourceTrueTypeFont: TrueType font '"
46 <<
getResourceName() <<
"' disabled. Define MYGUI_USE_FREETYE if you need TrueType fonts.");
70 return std::vector<std::pair<Char, Char>>();
143 void setMax(T& _var,
const T& _newValue)
145 if (_var < _newValue)
149 const std::map<const Char, const uint8> charMask{
154 const uint8 charMaskBlack = 0x00;
155 const uint8 charMaskWhite = 0xFF;
157 template<
bool LAMode>
160 static PixelFormat::Enum getFormat()
162 if constexpr (LAMode)
163 return PixelFormat::L8A8;
165 return PixelFormat::R8G8B8A8;
168 static size_t getNumBytes()
170 if constexpr (LAMode)
179 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha)
181 if constexpr (LAMode)
183 *_dest++ = _luminance;
188 *_dest++ = _luminance;
189 *_dest++ = _luminance;
190 *_dest++ = _luminance;
196 template<
bool LAMode,
bool FromSource = false,
bool Antialias = false>
197 struct Pixel : PixelBase<LAMode>
204 static void set(uint8*& _dest, uint8 _luminance, uint8 _alpha, uint8*& _source)
206 if constexpr (FromSource)
209 if constexpr (Antialias)
213 PixelBase<LAMode>::set(_dest, *_source, *_source);
218 PixelBase<LAMode>::set(_dest, _luminance, *_source);
226 PixelBase<LAMode>::set(_dest, _luminance, _alpha);
232 const int ResourceTrueTypeFont::mDefaultGlyphSpacing = 1;
233 const float ResourceTrueTypeFont::mDefaultTabWidth = 8.0f;
234 const float ResourceTrueTypeFont::mSelectedWidth = 1.0f;
235 const float ResourceTrueTypeFont::mCursorWidth = 2.0f;
239 if (mTexture !=
nullptr)
250 xml::ElementEnumerator node = _node->getElementEnumerator();
253 if (node->getName() ==
"Property")
255 std::string_view key = node->findAttribute(
"key");
256 std::string_view value = node->findAttribute(
"value");
259 else if (key ==
"Shader")
261 else if (key ==
"Size")
263 else if (key ==
"Resolution")
265 else if (key ==
"Antialias")
267 else if (key ==
"TabWidth")
269 else if (key ==
"OffsetHeight")
271 else if (key ==
"SubstituteCode")
273 else if (key ==
"Distance")
275 else if (key ==
"Hinting")
277 else if (key ==
"SpaceWidth")
282 _node->findAttribute(
"type")
283 <<
": Property '" << key <<
"' in font '" << _node->findAttribute(
"name")
284 <<
"' is deprecated; remove it to use automatic calculation.");
286 else if (key ==
"CursorWidth")
290 _node->findAttribute(
"type")
291 <<
": Property '" << key <<
"' in font '" << _node->findAttribute(
"name")
292 <<
"' is deprecated; value ignored.");
294 else if (key ==
"MsdfMode")
298 else if (key ==
"MsdfRange")
303 else if (node->getName() ==
"Codes")
306 xml::ElementEnumerator range = node->getElementEnumerator();
307 while (range.next(
"Code"))
309 std::string range_value;
310 if (range->findAttribute(
"range", range_value))
312 std::vector<std::string> parse_range =
utility::split(range_value);
313 if (!parse_range.empty())
324 if (mCharMap.empty())
328 range = node->getElementEnumerator();
329 while (range.next(
"Code"))
331 std::string range_value;
332 if (range->findAttribute(
"hide", range_value))
334 std::vector<std::string> parse_range =
utility::split(range_value);
335 if (!parse_range.empty())
351 GlyphMap::const_iterator glyphIter = mGlyphMap.find(_id);
353 if (glyphIter != mGlyphMap.end())
355 return &glyphIter->second;
358 return mSubstituteGlyphInfo;
368 return mDefaultHeight;
379 std::vector<std::pair<Char, Char>> result;
381 if (!mCharMap.empty())
383 CharMap::const_iterator iter = mCharMap.begin();
384 CharMap::const_iterator endIter = mCharMap.end();
387 Char rangeBegin = iter->first;
388 Char rangeEnd = rangeBegin;
391 for (++iter; iter != endIter; ++iter)
393 if (iter->first == rangeEnd + 1)
401 result.emplace_back(rangeBegin, rangeEnd);
404 rangeBegin = rangeEnd = iter->first;
409 result.emplace_back(rangeBegin, rangeEnd);
417 return mSubstituteCodePoint;
420 void ResourceTrueTypeFont::addCodePoint(
Char _codePoint)
422 mCharMap.insert(CharMap::value_type(_codePoint, 0));
425 void ResourceTrueTypeFont::removeCodePoint(
Char _codePoint)
427 mCharMap.erase(_codePoint);
432 CharMap::iterator positionHint = mCharMap.lower_bound(_first);
434 if (positionHint != mCharMap.begin())
437 for (
Char i = _first; i <= _second; ++i)
438 positionHint = mCharMap.insert(positionHint, CharMap::value_type(i, 0));
443 mCharMap.erase(mCharMap.lower_bound(_first), mCharMap.upper_bound(_second));
446 void ResourceTrueTypeFont::clearCodePoints()
453 if (mGlyphSpacing == -1)
454 mGlyphSpacing = mDefaultGlyphSpacing;
458 Pixel<true>::getFormat(),
469 ResourceTrueTypeFont::initialiseFreeType<true, true>();
471 ResourceTrueTypeFont::initialiseFreeType<true, false>();
476 ResourceTrueTypeFont::initialiseFreeType<false, true>();
478 ResourceTrueTypeFont::initialiseFreeType<false, false>();
482 template<
bool LAMode,
bool Antialias>
483 void ResourceTrueTypeFont::initialiseFreeType()
489 FT_Library ftLibrary;
491 if (FT_Init_FreeType(&ftLibrary) != 0)
492 MYGUI_EXCEPT(
"ResourceTrueTypeFont: Could not init the FreeType library!");
494 uint8* fontBuffer =
nullptr;
496 FT_Face ftFace = loadFace(ftLibrary, fontBuffer);
498 if (ftFace ==
nullptr)
501 FT_Done_FreeType(ftLibrary);
505 #ifdef MYGUI_MSDF_FONTS
506 msdfgen::FontHandle* msdfFont =
nullptr;
510 msdfFont = msdfgen::adoptFreetypeFont(ftFace);
522 int fontAscent = ftFace->size->metrics.ascender >> 6;
523 int fontDescent = -ftFace->size->metrics.descender >> 6;
525 TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(ftFace, ft_sfnt_os2);
529 setMax(fontAscent, os2->usWinAscent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
530 setMax(fontDescent, os2->usWinDescent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
532 setMax(fontAscent, os2->sTypoAscender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
533 setMax(fontDescent, -os2->sTypoDescender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM);
540 mDefaultHeight = fontAscent + fontDescent;
543 FT_Int32 ftLoadFlags = FT_LOAD_DEFAULT;
547 case HintingForceAuto: ftLoadFlags = FT_LOAD_FORCE_AUTOHINT;
break;
548 case HintingDisableAuto: ftLoadFlags = FT_LOAD_NO_AUTOHINT;
break;
549 case HintingDisableAll:
552 ftLoadFlags = FT_LOAD_NO_HINTING | FT_LOAD_RENDER;
554 case HintingUseNative: ftLoadFlags = FT_LOAD_DEFAULT;
break;
561 GlyphHeightMap glyphHeightMap;
569 for (CharMap::iterator iter = mCharMap.begin(); iter != mCharMap.end();)
571 const Char& codePoint = iter->first;
572 FT_UInt glyphIndex = FT_Get_Char_Index(ftFace, codePoint);
575 texWidth += createFaceGlyph(glyphIndex, codePoint, fontAscent, ftFace, ftLoadFlags, glyphHeightMap);
576 #ifdef MYGUI_MSDF_FONTS
578 texWidth += createMsdfFaceGlyph(codePoint, fontAscent, msdfFont, glyphHeightMap);
583 if (iter->second != 0)
586 mCharMap.erase(iter++);
592 if (spaceGlyphIter != mGlyphMap.end())
595 if (mSpaceWidth != 0.0f)
597 texWidth += (int)std::ceil(mSpaceWidth) - (int)std::ceil(spaceGlyphIter->second.width);
598 spaceGlyphIter->second.width = mSpaceWidth;
599 spaceGlyphIter->second.advance = mSpaceWidth;
603 if (mTabWidth == 0.0f)
604 mTabWidth = mDefaultTabWidth * spaceGlyphIter->second.advance;
610 FT_UInt nextGlyphIndex = (FT_UInt)ftFace->num_glyphs;
612 float height = (float)mDefaultHeight;
614 texWidth += createGlyph(
618 texWidth += createGlyph(
622 texWidth += createGlyph(
626 texWidth += createGlyph(
641 texWidth += createFaceGlyph(
648 #ifdef MYGUI_MSDF_FONTS
650 texWidth += createMsdfFaceGlyph(
659 mSubstituteGlyphInfo = &mGlyphMap.find(mSubstituteCodePoint)->second;
663 double averageGlyphHeight = 0.0;
665 for (
const auto& heightItem : glyphHeightMap)
666 averageGlyphHeight += heightItem.first * heightItem.second.size();
668 averageGlyphHeight /= mGlyphMap.size();
681 while (texWidth > texHeight)
694 if (texHeight > texWidth * 2)
697 int texX = mGlyphSpacing;
698 int texY = mGlyphSpacing;
700 for (
const auto& heightItem : glyphHeightMap)
702 for (
const auto& [key, info] : heightItem.second)
704 int glyphWidth = (int)std::ceil(info->width);
705 int glyphHeight = (int)std::ceil(info->height);
707 autoWrapGlyphPos(glyphWidth, texWidth, glyphHeight, texX, texY);
710 texX += mGlyphSpacing + glyphWidth;
715 }
while (texHeight > texWidth * 2);
731 mTexture->setInvalidateListener(
this);
733 if (!mShader.empty())
734 mTexture->setShader(mShader);
738 if (texBuffer !=
nullptr)
741 for (
uint8 *dest = texBuffer, *endDest = dest + texWidth * texHeight * Pixel<LAMode>::getNumBytes();
743 Pixel<LAMode, false, false>::set(dest, mMsdfMode ? charMaskBlack : charMaskWhite, charMaskBlack, dest);
746 renderGlyphs<LAMode, Antialias>(
754 #ifdef MYGUI_MSDF_FONTS
756 renderMsdfGlyphs(glyphHeightMap, msdfFont, texBuffer, texWidth, texHeight);
763 "ResourceTrueTypeFont: Font '"
764 <<
getResourceName() <<
"' using texture size " << texWidth <<
" x " << texHeight <<
".");
767 "ResourceTrueTypeFont: Font '"
768 <<
getResourceName() <<
"' using real height " << mDefaultHeight <<
" pixels.");
772 MYGUI_LOG(Error,
"ResourceTrueTypeFont: Error locking texture; pointer is nullptr.");
775 #ifdef MYGUI_MSDF_FONTS
778 msdfgen::destroyFont(msdfFont);
782 FT_Done_Face(ftFace);
783 FT_Done_FreeType(ftLibrary);
788 FT_Face ResourceTrueTypeFont::loadFace(
const FT_Library& _ftLibrary,
uint8*& _fontBuffer)
790 FT_Face result =
nullptr;
795 if (datastream ==
nullptr)
798 size_t fontBufferSize = datastream->
size();
799 _fontBuffer =
new uint8[fontBufferSize];
800 datastream->read(_fontBuffer, fontBufferSize);
803 datastream =
nullptr;
806 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, -1, &result) != 0)
809 FT_Long numFaces = result->num_faces;
810 FT_Long faceIndex = 0;
813 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
816 if (result->face_flags & FT_FACE_FLAG_SCALABLE)
820 FT_F26Dot6 ftSize = (FT_F26Dot6)(mSize * (1 << 6));
822 if (FT_Set_Char_Size(result, ftSize, 0, mResolution, mResolution) != 0)
826 if (mCharMap.empty())
832 FT_WinFNT_HeaderRec fnt;
836 std::map<float, FT_Long> faceSizes;
840 if (FT_Get_WinFNT_Header(result, &fnt) != 0)
844 std::make_pair((
float)fnt.nominal_point_size * fnt.vertical_resolution / mResolution, faceIndex));
846 FT_Done_Face(result);
848 if (++faceIndex < numFaces)
849 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
851 }
while (faceIndex < numFaces);
853 std::map<float, FT_Long>::const_iterator iter = faceSizes.lower_bound(mSize);
855 faceIndex = (iter != faceSizes.end()) ? iter->second : faceSizes.rbegin()->second;
857 if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
862 if (FT_Select_Size(result, 0) != 0)
867 if (mCharMap.empty())
874 if (fnt.charset == FT_WinFNT_ID_CP1252)
886 if (fnt.charset == FT_WinFNT_ID_CP1252)
896 void ResourceTrueTypeFont::autoWrapGlyphPos(
int _glyphWidth,
int _texWidth,
int _lineHeight,
int& _texX,
int& _texY)
899 if (_glyphWidth > 0 && _texX + mGlyphSpacing + _glyphWidth > _texWidth)
901 _texX = mGlyphSpacing;
902 _texY += mGlyphSpacing + _lineHeight;
906 GlyphInfo ResourceTrueTypeFont::createFaceGlyphInfo(
Char _codePoint,
int _fontAscent, FT_GlyphSlot _glyph)
const
908 float bearingX = _glyph->metrics.horiBearingX / 64.0f;
916 std::max((
float)_glyph->bitmap.width, _glyph->metrics.width / 64.0f),
917 std::max((
float)_glyph->bitmap.rows, _glyph->metrics.height / 64.0f),
918 (_glyph->advance.x / 64.0f) - bearingX,
920 std::floor(_fontAscent - (_glyph->metrics.horiBearingY / 64.0f) - mOffsetHeight)};
923 int ResourceTrueTypeFont::createGlyph(
926 GlyphHeightMap& _glyphHeightMap)
928 int width = (int)std::ceil(_glyphInfo.width);
929 int height = (int)std::ceil(_glyphInfo.height);
931 mCharMap[_glyphInfo.codePoint] = _glyphIndex;
932 GlyphInfo& info = mGlyphMap.insert(GlyphMap::value_type(_glyphInfo.codePoint, _glyphInfo)).first->second;
933 _glyphHeightMap[height].insert(std::make_pair(_glyphIndex, &info));
935 return (width > 0) ? mGlyphSpacing + width : 0;
938 int ResourceTrueTypeFont::createFaceGlyph(
942 const FT_Face& _ftFace,
943 FT_Int32 _ftLoadFlags,
944 GlyphHeightMap& _glyphHeightMap)
946 if (mGlyphMap.find(_codePoint) == mGlyphMap.end())
948 if (FT_Load_Glyph(_ftFace, _glyphIndex, _ftLoadFlags) == 0)
951 createFaceGlyphInfo(_codePoint, _fontAscent, _ftFace->glyph),
955 "ResourceTrueTypeFont: Cannot load glyph "
956 << _glyphIndex <<
" for character " << _codePoint <<
" in font '" <<
getResourceName() <<
"'.");
960 mCharMap[_codePoint] = _glyphIndex;
966 template<
bool LAMode,
bool Antialias>
967 void ResourceTrueTypeFont::renderGlyphs(
968 const GlyphHeightMap& _glyphHeightMap,
969 const FT_Library& _ftLibrary,
970 const FT_Face& _ftFace,
971 FT_Int32 _ftLoadFlags,
977 FT_Bitmap_New(&ftBitmap);
979 int texX = mGlyphSpacing;
980 int texY = mGlyphSpacing;
982 for (
const auto& sameHeightGlyphs : _glyphHeightMap)
984 int glyphHeight = sameHeightGlyphs.first;
985 for (
const auto& glyph : sameHeightGlyphs.second)
987 GlyphInfo& info = *glyph.second;
989 switch (info.codePoint)
994 renderGlyph<LAMode, false, false>(
998 charMask.find(info.codePoint)->second,
1008 GlyphMap::iterator glyphIter = mGlyphMap.find(info.codePoint);
1009 if (glyphIter != mGlyphMap.end())
1011 glyphIter->second.width = 0.0f;
1012 glyphIter->second.uvRect.right = glyphIter->second.uvRect.left;
1019 renderGlyph<LAMode, false, false>(
1023 charMask.find(info.codePoint)->second,
1033 if (FT_Load_Glyph(_ftFace, glyph.first, _ftLoadFlags | FT_LOAD_RENDER) == 0)
1035 if (_ftFace->glyph->bitmap.buffer !=
nullptr)
1037 uint8* glyphBuffer =
nullptr;
1039 switch (_ftFace->glyph->bitmap.pixel_mode)
1041 case FT_PIXEL_MODE_GRAY: glyphBuffer = _ftFace->glyph->bitmap.buffer;
break;
1043 case FT_PIXEL_MODE_MONO:
1045 if (FT_Bitmap_Convert(_ftLibrary, &_ftFace->glyph->bitmap, &ftBitmap, 1) == 0)
1048 for (
uint8 *p = ftBitmap.buffer, *endP = p + ftBitmap.width * ftBitmap.rows;
1053 glyphBuffer = ftBitmap.buffer;
1058 if (glyphBuffer !=
nullptr)
1059 renderGlyph<LAMode, true, Antialias>(
1077 "ResourceTrueTypeFont: Cannot render glyph "
1078 << glyph.first <<
" for character " << info.codePoint <<
" in font '"
1086 FT_Bitmap_Done(_ftLibrary, &ftBitmap);
1089 template<
bool LAMode,
bool UseBuffer,
bool Antialias>
1090 void ResourceTrueTypeFont::renderGlyph(
1101 uint8* _glyphBuffer)
1103 int width = (int)std::ceil(_info.width);
1104 int height = (int)std::ceil(_info.height);
1106 autoWrapGlyphPos(width, _texWidth, _lineHeight, _texX, _texY);
1108 uint8* dest = _texBuffer + (_texY * _texWidth + _texX) * Pixel<LAMode>::getNumBytes();
1111 ptrdiff_t destNextRow = (_texWidth - width) * Pixel<LAMode>::getNumBytes();
1113 if (!mMsdfMode || !UseBuffer)
1115 for (
int j = height; j > 0; --j)
1118 for (i = width; i > 1; i -= 2)
1120 Pixel<LAMode, UseBuffer, Antialias>::set(dest, _luminance0, _alpha, _glyphBuffer);
1121 Pixel<LAMode, UseBuffer, Antialias>::set(dest, _luminance1, _alpha, _glyphBuffer);
1125 Pixel<LAMode, UseBuffer, Antialias>::set(dest, _luminance0, _alpha, _glyphBuffer);
1127 dest += destNextRow;
1132 for (
int y = 0; y < height; ++y)
1134 for (
int x = 0; x < width; ++x)
1136 for (
int i = 0; i < 3; ++i)
1138 *dest++ = *_glyphBuffer++;
1143 dest += destNextRow;
1148 _info.uvRect.left = (float)_texX / _texWidth;
1149 _info.uvRect.top = (float)_texY / _texHeight;
1150 _info.uvRect.right = (float)(_texX + _info.width) / _texWidth;
1151 _info.uvRect.bottom = (float)(_texY + _info.height) / _texHeight;
1154 _texX += mGlyphSpacing + width;
1157 #ifdef MYGUI_MSDF_FONTS
1158 GlyphInfo ResourceTrueTypeFont::createMsdfFaceGlyphInfo(
1160 const msdfgen::Shape& _shape,
1164 msdfgen::Shape::Bounds bounds = _shape.getBounds();
1165 double range = mMsdfRange / 2.0;
1166 if (_shape.contours.empty())
1168 bounds = {0, 0, 0, 0};
1172 double bearingX = bounds.l;
1176 bounds.r - bounds.l + 2 * range,
1177 bounds.t - bounds.b + 2 * range,
1178 _advance - bearingX + range,
1180 std::floor(_fontAscent - bounds.t - mOffsetHeight - range));
1183 int ResourceTrueTypeFont::createMsdfGlyph(
const GlyphInfo& _glyphInfo, GlyphHeightMap& _glyphHeightMap)
1185 int width = (int)std::ceil(_glyphInfo.width);
1186 int height = (int)std::ceil(_glyphInfo.height);
1188 mCharMap[_glyphInfo.codePoint] = _glyphInfo.codePoint;
1189 GlyphInfo& info = mGlyphMap.insert(GlyphMap::value_type(_glyphInfo.codePoint, _glyphInfo)).first->second;
1190 _glyphHeightMap[height].insert(std::make_pair(_glyphInfo.codePoint, &info));
1192 return (width > 0) ? mGlyphSpacing + width : 0;
1195 int ResourceTrueTypeFont::createMsdfFaceGlyph(
1198 msdfgen::FontHandle* _fontHandle,
1199 GlyphHeightMap& _glyphHeightMap)
1201 if (mGlyphMap.find(_codePoint) == mGlyphMap.end())
1203 msdfgen::Shape shape;
1205 if (msdfgen::loadGlyph(shape, _fontHandle, _codePoint, &advance))
1206 createMsdfGlyph(createMsdfFaceGlyphInfo(_codePoint, shape, advance, _fontAscent), _glyphHeightMap);
1210 "ResourceTrueTypeFont: Cannot load msdf glyph for character "
1215 mCharMap[_codePoint] = _codePoint;
1221 void ResourceTrueTypeFont::renderMsdfGlyphs(
1222 const GlyphHeightMap& _glyphHeightMap,
1223 msdfgen::FontHandle* _fontHandle,
1228 int texX = mGlyphSpacing, texY = mGlyphSpacing;
1230 for (
const auto& sameHeightGlyphs : _glyphHeightMap)
1232 int glyphHeight = sameHeightGlyphs.first;
1233 for (
const auto& glyph : sameHeightGlyphs.second)
1235 GlyphInfo& info = *glyph.second;
1237 switch (info.codePoint)
1242 renderGlyph<false, false, false>(
1246 charMask.find(info.codePoint)->second,
1256 GlyphMap::iterator glyphIter = mGlyphMap.find(info.codePoint);
1257 if (glyphIter != mGlyphMap.end())
1259 glyphIter->second.width = 0.0f;
1260 glyphIter->second.uvRect.right = glyphIter->second.uvRect.left;
1267 renderGlyph<false, false, false>(
1271 charMask.find(info.codePoint)->second,
1281 msdfgen::Shape shape;
1282 if (loadGlyph(shape, _fontHandle, info.codePoint))
1284 msdfgen::Shape::Bounds bounds = shape.getBounds();
1285 double range = mMsdfRange / 2.0;
1286 if (shape.contours.empty())
1288 bounds = {0, 0, 0, 0};
1293 edgeColoringSimple(shape, 3.0);
1295 msdfgen::Bitmap<float, 3> msdf(
1296 std::ceil(bounds.r - bounds.l + 2 * range),
1297 std::ceil(bounds.t - bounds.b + 2 * range));
1298 msdfgen::generateMSDF(
1303 msdfgen::Vector2(-bounds.l + range, -bounds.b + range));
1313 uint8* glyphBuffer =
new uint8[msdf.width() * msdf.height() * 3];
1314 uint8* glyphBufferPointer = glyphBuffer;
1315 for (
int y = 0; y < msdf.height(); ++y)
1317 for (
int x = 0; x < msdf.width(); ++x)
1319 for (
int i = 0; i < 3; ++i)
1322 *glyphBufferPointer++ =
1323 msdfgen::pixelFloatToByte(msdf(x, msdf.height() - y - 1)[2 - i]);
1328 renderGlyph<false, true, false>(
1340 delete[] glyphBuffer;
1346 "ResourceTrueTypeFont: Cannot render glyph for character "
1373 mResolution = _value;
1378 if (_value ==
"use_native")
1379 mHinting = HintingUseNative;
1380 else if (_value ==
"force_auto")
1381 mHinting = HintingForceAuto;
1382 else if (_value ==
"disable_auto")
1383 mHinting = HintingDisableAuto;
1384 else if (_value ==
"disable_all")
1385 mHinting = HintingDisableAll;
1387 mHinting = HintingUseNative;
1392 mAntialias = _value;
1402 mOffsetHeight = _value;
1407 mSubstituteCodePoint = _value;
1412 mGlyphSpacing = _value;
1417 #ifndef MYGUI_MSDF_FONTS
1421 "MsdfMode flag ignored Define MYGUI_MSDF_FONTS if you need msdf fonts, msdf mode ignored.");
1429 mMsdfRange = _value;
#define MYGUI_EXCEPT(dest)
#define MYGUI_LOG(level, text)
virtual void freeData(IDataStream *_data)=0
virtual IDataStream * getData(const std::string &_name) const =0
static DataManager & getInstance()
const std::string & getResourceName() const
virtual void createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format)=0
virtual ITexture * createTexture(const std::string &_name)=0
virtual void destroyTexture(ITexture *_texture)=0
static RenderManager & getInstance()
virtual bool isFormatSupported(PixelFormat _format, TextureUsage _usage)
void setAntialias(bool _value)
void setMsdfMode(bool _value)
void setMsdfRange(int _value)
void setShader(std::string_view _value)
void setResolution(unsigned int _value)
void setSource(std::string_view _value)
void textureInvalidate(ITexture *_texture) override
void setOffsetHeight(int _value)
const GlyphInfo * getGlyphInfo(Char _id) const override
void removeCodePointRange(Char _first, Char _second)
void setSubstituteCode(int _value)
void addCodePointRange(Char _first, Char _second)
void setHinting(std::string_view _value)
~ResourceTrueTypeFont() override
ITexture * getTextureFont() const override
std::vector< std::pair< Char, Char > > getCodePointRanges() const
void deserialization(xml::ElementPtr _node, Version _version) override
void setSize(float _value)
int getDefaultHeight() const override
Char getSubstituteCodePoint() const
void setDistance(int _value)
void setTabWidth(float _value)
static Type firstPO2From(Type _value)
unsigned int parseUInt(std::string_view _value)
bool parseBool(std::string_view _value)
float parseFloat(std::string_view _value)
std::vector< std::string > split(std::string_view _source, std::string_view _delims="\t\n ")
std::string toString(T _value)
int parseInt(std::string_view _value)