@@ -68,12 +68,10 @@ bool FontFaceHandleHarfBuzz::Initialize(FontFaceHandleFreetype face, int font_si
68
68
if (!FreeType::InitialiseFaceHandle (ft_face, font_size, glyphs, metrics, load_default_glyphs))
69
69
return false ;
70
70
71
- has_kerning = Rml::FreeType::HasKerning (ft_face);
72
- FillKerningPairCache ();
73
-
74
71
hb_font = hb_ft_font_create_referenced ((FT_Face)ft_face);
75
72
RMLUI_ASSERT (hb_font != nullptr );
76
73
hb_font_set_ptem (hb_font, (float )font_size);
74
+ hb_ft_font_set_funcs (hb_font);
77
75
78
76
// Generate the default layer and layer configuration.
79
77
base_layer = GetOrCreateLayer (nullptr );
@@ -98,7 +96,7 @@ const FallbackFontGlyphMap& FontFaceHandleHarfBuzz::GetFallbackGlyphs() const
98
96
}
99
97
100
98
int FontFaceHandleHarfBuzz::GetStringWidth (StringView string, const TextShapingContext& text_shaping_context,
101
- const LanguageDataMap& registered_languages, Character prior_character)
99
+ const LanguageDataMap& registered_languages, Character /* prior_character*/ )
102
100
{
103
101
int width = 0 ;
104
102
@@ -109,10 +107,9 @@ int FontFaceHandleHarfBuzz::GetStringWidth(StringView string, const TextShapingC
109
107
hb_buffer_add_utf8 (shaping_buffer, string.begin (), (int )string.size (), 0 , (int )string.size ());
110
108
hb_shape (hb_font, shaping_buffer, nullptr , 0 );
111
109
112
- FontGlyphIndex prior_glyph_codepoint = FreeType::GetGlyphIndexFromCharacter (ft_face, prior_character);
113
-
114
110
unsigned int glyph_count = 0 ;
115
111
hb_glyph_info_t * glyph_info = hb_buffer_get_glyph_infos (shaping_buffer, &glyph_count);
112
+ hb_glyph_position_t * glyph_positions = hb_buffer_get_glyph_positions (shaping_buffer, &glyph_count);
116
113
117
114
for (int g = 0 ; g < (int )glyph_count; ++g)
118
115
{
@@ -121,19 +118,19 @@ int FontFaceHandleHarfBuzz::GetStringWidth(StringView string, const TextShapingC
121
118
if (IsASCIIControlCharacter (character))
122
119
continue ;
123
120
124
- FontGlyphIndex glyph_codepoint = glyph_info[g].codepoint ;
125
- const FontGlyph* glyph = GetOrAppendGlyph (glyph_codepoint , character);
121
+ FontGlyphIndex glyph_index = glyph_info[g].codepoint ;
122
+ const FontGlyph* glyph = GetOrAppendGlyph (glyph_index , character);
126
123
if (!glyph)
127
124
continue ;
128
125
129
- // Adjust the cursor for the kerning between this character and the previous one.
130
- width += GetKerning (prior_glyph_codepoint, glyph_codepoint);
131
-
132
126
// Adjust the cursor for this character's advance.
133
- width += glyph->advance ;
134
- width += (int )text_shaping_context.letter_spacing ;
127
+ if (glyph_index != 0 )
128
+ width += glyph_positions[g].x_advance >> 6 ;
129
+ else
130
+ // Use the unshaped advance for unsupported characters.
131
+ width += glyph->advance ;
135
132
136
- prior_glyph_codepoint = glyph_codepoint ;
133
+ width += ( int )text_shaping_context. letter_spacing ;
137
134
}
138
135
139
136
hb_buffer_destroy (shaping_buffer);
@@ -265,7 +262,6 @@ int FontFaceHandleHarfBuzz::GenerateString(RenderManager& render_manager, Textur
265
262
RMLUI_ASSERT (geometry_index + num_textures <= (int )mesh_list.size ());
266
263
267
264
line_width = 0 ;
268
- FontGlyphIndex prior_glyph_codepoint = 0 ;
269
265
270
266
// Set the mesh and textures to the geometries.
271
267
for (int tex_index = 0 ; tex_index < num_textures; ++tex_index)
@@ -279,6 +275,7 @@ int FontFaceHandleHarfBuzz::GenerateString(RenderManager& render_manager, Textur
279
275
280
276
unsigned int glyph_count = 0 ;
281
277
hb_glyph_info_t * glyph_info = hb_buffer_get_glyph_infos (shaping_buffer, &glyph_count);
278
+ hb_glyph_position_t * glyph_positions = hb_buffer_get_glyph_positions (shaping_buffer, &glyph_count);
282
279
283
280
mesh_list[geometry_index].mesh .indices .reserve (string.size () * 6 );
284
281
mesh_list[geometry_index].mesh .vertices .reserve (string.size () * 4 );
@@ -291,25 +288,28 @@ int FontFaceHandleHarfBuzz::GenerateString(RenderManager& render_manager, Textur
291
288
if (IsASCIIControlCharacter (character))
292
289
continue ;
293
290
294
- FontGlyphIndex glyph_codepoint = glyph_info[g].codepoint ;
295
- const FontGlyph* glyph = GetOrAppendGlyph (glyph_codepoint , character);
291
+ FontGlyphIndex glyph_index = glyph_info[g].codepoint ;
292
+ const FontGlyph* glyph = GetOrAppendGlyph (glyph_index , character);
296
293
if (!glyph)
297
294
continue ;
298
295
299
- // Adjust the cursor for the kerning between this character and the previous one.
300
- line_width += GetKerning (prior_glyph_codepoint, glyph_codepoint);
301
-
302
296
ColourbPremultiplied glyph_color = layer_colour;
303
297
// Use white vertex colors on RGB glyphs.
304
298
if (layer == base_layer && glyph->color_format == ColorFormat::RGBA8)
305
299
glyph_color = ColourbPremultiplied (layer_colour.alpha , layer_colour.alpha );
306
300
307
- layer->GenerateGeometry (&mesh_list[geometry_index], glyph_codepoint, character, Vector2f (position.x + line_width, position.y ),
308
- glyph_color);
301
+ Vector2f glyph_offset = {float (glyph_positions[g].x_offset >> 6 ), float (glyph_positions[g].y_offset >> 6 )};
302
+ Vector2f glyph_geometry_position = Vector2f{position.x + line_width, position.y } + glyph_offset;
303
+ layer->GenerateGeometry (&mesh_list[geometry_index], glyph_index, character, glyph_geometry_position, glyph_color);
304
+
305
+ // Adjust the cursor for this character's advance.
306
+ if (glyph_index != 0 )
307
+ line_width += glyph_positions[g].x_advance >> 6 ;
308
+ else
309
+ // Use the unshaped advance for unsupported characters.
310
+ line_width += glyph->advance ;
309
311
310
- line_width += glyph->advance ;
311
312
line_width += (int )text_shaping_context.letter_spacing ;
312
- prior_glyph_codepoint = glyph_codepoint;
313
313
}
314
314
315
315
geometry_index += num_textures;
@@ -383,49 +383,6 @@ bool FontFaceHandleHarfBuzz::AppendFallbackGlyph(Character character)
383
383
return false ;
384
384
}
385
385
386
- void FontFaceHandleHarfBuzz::FillKerningPairCache ()
387
- {
388
- if (!has_kerning)
389
- return ;
390
-
391
- static constexpr char32_t KerningCache_AsciiSubsetBegin = 32 ;
392
- static constexpr char32_t KerningCache_AsciiSubsetLast = 126 ;
393
-
394
- for (char32_t i = KerningCache_AsciiSubsetBegin; i <= KerningCache_AsciiSubsetLast; i++)
395
- {
396
- for (char32_t j = KerningCache_AsciiSubsetBegin; j <= KerningCache_AsciiSubsetLast; j++)
397
- {
398
- const bool first_iteration = (i == KerningCache_AsciiSubsetBegin && j == KerningCache_AsciiSubsetBegin);
399
-
400
- // Fetch the kerning from the font face. Submit zero font size on subsequent iterations for performance reasons.
401
- const int kerning = FreeType::GetKerning (ft_face, first_iteration ? metrics.size : 0 ,
402
- FreeType::GetGlyphIndexFromCharacter (ft_face, Character (i)), FreeType::GetGlyphIndexFromCharacter (ft_face, Character (j)));
403
- if (kerning != 0 )
404
- {
405
- kerning_pair_cache.emplace (AsciiPair ((i << 8 ) | j), KerningIntType (kerning));
406
- }
407
- }
408
- }
409
- }
410
-
411
- int FontFaceHandleHarfBuzz::GetKerning (FontGlyphIndex lhs, FontGlyphIndex rhs) const
412
- {
413
- // Check if we have no kerning, or if we are have an unsupported character.
414
- if (!has_kerning || lhs == 0 || rhs == 0 )
415
- return 0 ;
416
-
417
- // See if the kerning pair has been cached.
418
- const auto it = kerning_pair_cache.find (AsciiPair ((int (lhs) << 8 ) | int (rhs)));
419
- if (it != kerning_pair_cache.end ())
420
- {
421
- return it->second ;
422
- }
423
-
424
- // Fetch it from the font face instead.
425
- const int result = FreeType::GetKerning (ft_face, metrics.size , lhs, rhs);
426
- return result;
427
- }
428
-
429
386
const FontGlyph* FontFaceHandleHarfBuzz::GetOrAppendGlyph (FontGlyphIndex glyph_index, Character& character, bool look_in_fallback_fonts)
430
387
{
431
388
if (glyph_index == 0 && look_in_fallback_fonts && character != Character::Replacement)
0 commit comments