FontFaceHandle.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://github.com/mikke89/RmlUi
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. * Copyright (c) 2019 The RmlUi Team, and contributors
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. #include "precompiled.h"
  29. #ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
  30. #include "FontFaceHandle.h"
  31. #include "FontFaceLayer.h"
  32. #include <algorithm>
  33. #include "../TextureLayout.h"
  34. namespace Rml {
  35. namespace Core {
  36. BitmapFont::FontFaceHandle::FontFaceHandle()
  37. {
  38. bm_face = nullptr;
  39. texture_width = 0;
  40. texture_height = 0;
  41. }
  42. BitmapFont::FontFaceHandle::~FontFaceHandle()
  43. {
  44. }
  45. // Initialises the handle so it is able to render text.
  46. bool BitmapFont::FontFaceHandle::Initialise(BitmapFontDefinitions *_bm_face, const String& _charset, int _size)
  47. {
  48. bm_face = _bm_face;
  49. size = _size;
  50. line_height = _size;
  51. texture_width = bm_face->CommonCharactersInfo.ScaleWidth;
  52. texture_height = bm_face->CommonCharactersInfo.ScaleHeight;
  53. raw_charset = _charset;
  54. // Construct proper path to texture
  55. URL fnt_source = bm_face->Face.Source;
  56. URL bitmap_source = bm_face->Face.BitmapSource;
  57. if(bitmap_source.GetPath().empty())
  58. {
  59. texture_source = fnt_source.GetPath() + bitmap_source.GetFileName();
  60. if(!bitmap_source.GetExtension().empty())
  61. {
  62. texture_source += "." + bitmap_source.GetExtension();
  63. }
  64. }
  65. else
  66. {
  67. texture_source = bitmap_source.GetPathedFileName();
  68. }
  69. if (!UnicodeRange::BuildList(charset, raw_charset))
  70. {
  71. Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", raw_charset.c_str());
  72. return false;
  73. }
  74. // Construct the list of the characters specified by the charset.
  75. for (size_t i = 0; i < charset.size(); ++i)
  76. BuildGlyphMap(bm_face, charset[i]);
  77. // Generate the metrics for the handle.
  78. GenerateMetrics(bm_face);
  79. // Generate the default layer and layer configuration.
  80. base_layer = GenerateLayer(nullptr);
  81. layer_configurations.push_back(LayerConfiguration());
  82. layer_configurations.back().push_back(base_layer);
  83. return true;
  84. }
  85. void BitmapFont::FontFaceHandle::GenerateMetrics(BitmapFontDefinitions *bm_face)
  86. {
  87. line_height = bm_face->CommonCharactersInfo.LineHeight;
  88. baseline = bm_face->CommonCharactersInfo.BaseLine;
  89. underline_position = (float)line_height - bm_face->CommonCharactersInfo.BaseLine;
  90. baseline += int( underline_position / 1.6f );
  91. underline_thickness = 1.0f;
  92. average_advance = 0;
  93. for (FontGlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
  94. average_advance += i->advance;
  95. // Bring the total advance down to the average advance, but scaled up 10%, just to be on the safe side.
  96. average_advance = Math::RealToInteger((float) average_advance / (glyphs.size() * 0.9f));
  97. // Determine the x-height of this font face.
  98. word x = (word) 'x';
  99. int index = bm_face->BM_Helper_GetCharacterTableIndex( x );// FT_Get_Char_Index(ft_face, x);
  100. if ( index >= 0)
  101. x_height = bm_face->CharactersInfo[ index ].Height;
  102. else
  103. x_height = 0;
  104. }
  105. void BitmapFont::FontFaceHandle::BuildGlyphMap(BitmapFontDefinitions *bm_face, const UnicodeRange& unicode_range)
  106. {
  107. glyphs.resize(unicode_range.max_codepoint + 1);
  108. for (word character_code = (word) (Math::Max< unsigned int >(unicode_range.min_codepoint, 32)); character_code <= unicode_range.max_codepoint; ++character_code)
  109. {
  110. int index = bm_face->BM_Helper_GetCharacterTableIndex( character_code );
  111. if ( index < 0 )
  112. {
  113. continue;
  114. }
  115. FontGlyph glyph;
  116. glyph.character = character_code;
  117. BuildGlyph(glyph, &bm_face->CharactersInfo[ index ] );
  118. glyphs[character_code] = glyph;
  119. }
  120. }
  121. void BitmapFont::FontFaceHandle::BuildGlyph(FontGlyph& glyph, CharacterInfo *bm_glyph)
  122. {
  123. // Set the glyph's dimensions.
  124. glyph.dimensions.x = bm_glyph->Width;
  125. glyph.dimensions.y = bm_glyph->Height;
  126. // Set the glyph's bearing.
  127. glyph.bearing.x = bm_glyph->XOffset;
  128. glyph.bearing.y = bm_glyph->YOffset;
  129. // Set the glyph's advance.
  130. glyph.advance = bm_glyph->Advance;
  131. // Set the glyph's bitmap position.
  132. glyph.bitmap_dimensions.x = bm_glyph->X;
  133. glyph.bitmap_dimensions.y = bm_glyph->Y;
  134. glyph.bitmap_data = nullptr;
  135. }
  136. int BitmapFont::FontFaceHandle::GetKerning(word lhs, word rhs) const
  137. {
  138. if( bm_face != nullptr)
  139. {
  140. return bm_face->BM_Helper_GetXKerning(lhs, rhs);
  141. }
  142. return 0;
  143. }
  144. Rml::Core::FontFaceLayer* BitmapFont::FontFaceHandle::CreateNewLayer()
  145. {
  146. return new BitmapFont::FontFaceLayer();
  147. }
  148. }
  149. }
  150. #endif