FontFaceHandle.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. #include "FontFaceHandle.h"
  30. #include "FontFaceLayer.h"
  31. #include <algorithm>
  32. #include "../TextureLayout.h"
  33. namespace Rml {
  34. namespace Core {
  35. BitmapFont::FontFaceHandle::FontFaceHandle()
  36. {
  37. bm_face = nullptr;
  38. texture_width = 0;
  39. texture_height = 0;
  40. }
  41. BitmapFont::FontFaceHandle::~FontFaceHandle()
  42. {
  43. }
  44. // Initialises the handle so it is able to render text.
  45. bool BitmapFont::FontFaceHandle::Initialise(BitmapFontDefinitions *_bm_face, const String& _charset, int _size)
  46. {
  47. bm_face = _bm_face;
  48. size = _size;
  49. line_height = _size;
  50. texture_width = bm_face->CommonCharactersInfo.ScaleWidth;
  51. texture_height = bm_face->CommonCharactersInfo.ScaleHeight;
  52. raw_charset = _charset;
  53. // Construct proper path to texture
  54. URL fnt_source = bm_face->Face.Source;
  55. URL bitmap_source = bm_face->Face.BitmapSource;
  56. if(bitmap_source.GetPath().empty())
  57. {
  58. texture_source = fnt_source.GetPath() + bitmap_source.GetFileName();
  59. if(!bitmap_source.GetExtension().empty())
  60. {
  61. texture_source += "." + bitmap_source.GetExtension();
  62. }
  63. }
  64. else
  65. {
  66. texture_source = bitmap_source.GetPathedFileName();
  67. }
  68. if (!UnicodeRange::BuildList(charset, raw_charset))
  69. {
  70. Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", raw_charset.c_str());
  71. return false;
  72. }
  73. // Construct the list of the characters specified by the charset.
  74. for (size_t i = 0; i < charset.size(); ++i)
  75. BuildGlyphMap(bm_face, charset[i]);
  76. // Generate the metrics for the handle.
  77. GenerateMetrics(bm_face);
  78. // Generate the default layer and layer configuration.
  79. base_layer = GenerateLayer(nullptr);
  80. layer_configurations.push_back(LayerConfiguration());
  81. layer_configurations.back().push_back(base_layer);
  82. return true;
  83. }
  84. void BitmapFont::FontFaceHandle::GenerateMetrics(BitmapFontDefinitions *bm_face)
  85. {
  86. line_height = bm_face->CommonCharactersInfo.LineHeight;
  87. baseline = bm_face->CommonCharactersInfo.BaseLine;
  88. underline_position = (float)line_height - bm_face->CommonCharactersInfo.BaseLine;
  89. baseline += int( underline_position / 1.6f );
  90. underline_thickness = 1.0f;
  91. average_advance = 0;
  92. for (FontGlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
  93. average_advance += i->advance;
  94. // Bring the total advance down to the average advance, but scaled up 10%, just to be on the safe side.
  95. average_advance = Math::RealToInteger((float) average_advance / (glyphs.size() * 0.9f));
  96. // Determine the x-height of this font face.
  97. word x = (word) 'x';
  98. int index = bm_face->BM_Helper_GetCharacterTableIndex( x );// FT_Get_Char_Index(ft_face, x);
  99. if ( index >= 0)
  100. x_height = bm_face->CharactersInfo[ index ].Height;
  101. else
  102. x_height = 0;
  103. }
  104. void BitmapFont::FontFaceHandle::BuildGlyphMap(BitmapFontDefinitions *bm_face, const UnicodeRange& unicode_range)
  105. {
  106. glyphs.resize(unicode_range.max_codepoint + 1);
  107. for (word character_code = (word) (Math::Max< unsigned int >(unicode_range.min_codepoint, 32)); character_code <= unicode_range.max_codepoint; ++character_code)
  108. {
  109. int index = bm_face->BM_Helper_GetCharacterTableIndex( character_code );
  110. if ( index < 0 )
  111. {
  112. continue;
  113. }
  114. FontGlyph glyph;
  115. glyph.character = character_code;
  116. BuildGlyph(glyph, &bm_face->CharactersInfo[ index ] );
  117. glyphs[character_code] = glyph;
  118. }
  119. }
  120. void BitmapFont::FontFaceHandle::BuildGlyph(FontGlyph& glyph, CharacterInfo *bm_glyph)
  121. {
  122. // Set the glyph's dimensions.
  123. glyph.dimensions.x = bm_glyph->Width;
  124. glyph.dimensions.y = bm_glyph->Height;
  125. // Set the glyph's bearing.
  126. glyph.bearing.x = bm_glyph->XOffset;
  127. glyph.bearing.y = bm_glyph->YOffset;
  128. // Set the glyph's advance.
  129. glyph.advance = bm_glyph->Advance;
  130. // Set the glyph's bitmap position.
  131. glyph.bitmap_dimensions.x = bm_glyph->X;
  132. glyph.bitmap_dimensions.y = bm_glyph->Y;
  133. glyph.bitmap_data = nullptr;
  134. }
  135. int BitmapFont::FontFaceHandle::GetKerning(word lhs, word rhs) const
  136. {
  137. if( bm_face != nullptr)
  138. {
  139. return bm_face->BM_Helper_GetXKerning(lhs, rhs);
  140. }
  141. return 0;
  142. }
  143. Rml::Core::FontFaceLayer* BitmapFont::FontFaceHandle::CreateNewLayer()
  144. {
  145. return new BitmapFont::FontFaceLayer();
  146. }
  147. }
  148. }