@@ -101,20 +101,20 @@ namespace FreeType
101101 using namespace std ;
102102 using namespace LLUtils ;
103103
104- const auto textCreateParams = measureParams.createParams ;
105- const BitFlags<TextCreateFlags> createFlags{ textCreateParams.flags };
106- const bool useMetaText = createFlags.test (TextCreateFlags::UseMetaText);
104+ const auto & textCreateParams = measureParams.createParams ;
105+ const BitFlags<TextCreateFlags> createFlags{textCreateParams.flags };
106+ const bool useMetaText = createFlags.test (TextCreateFlags::UseMetaText);
107107 const bool lineEndFixedWidth = createFlags.test (TextCreateFlags::LineEndFixedWidth);
108- const bool usebidiText = createFlags.test (TextCreateFlags::Bidirectional);
108+ const bool usebidiText = createFlags.test (TextCreateFlags::Bidirectional);
109109
110- const string_type text = textCreateParams.text ;
111- const string_type& fontPath = textCreateParams.fontPath ;
112- const uint16_t fontSize = textCreateParams.fontSize ;
113- const uint32_t OutlineWidth = textCreateParams.outlineWidth ;
114- FT_Render_Mode textRenderMOde = FreeTypeRenderer::GetRenderMode (textCreateParams.renderMode );
110+ const string_type& text = textCreateParams.text ;
111+ const string_type& fontPath = textCreateParams.fontPath ;
112+ const uint16_t fontSize = textCreateParams.fontSize ;
113+ const uint32_t OutlineWidth = textCreateParams.outlineWidth ;
114+ FT_Render_Mode textRenderMOde = FreeTypeRenderer::GetRenderMode (textCreateParams.renderMode );
115115 FT_Render_Mode outlineRenderMode = FreeTypeRenderer::GetRenderMode (textCreateParams.renderMode );
116- const bool renderOutline = OutlineWidth > 0 ;
117- mesureResult = {};
116+ const bool renderOutline = OutlineWidth > 0 ;
117+ mesureResult = {};
118118 if (measureParams.createParams .text .empty () == false )
119119 {
120120
@@ -201,6 +201,13 @@ namespace FreeType
201201 if (FT_Error error = FT_Get_Glyph (face->glyph , &glyph))
202202 LL_EXCEPTION (LLUtils::Exception::ErrorCode::RuntimeError, std::format (" FreeType error {0}, {1}" , error, GenerateFreeTypeErrorString (" unable to render glyph" ,error)));
203203
204+ // Bitmap conversion replaces the handle; release the surviving glyph even if measurement fails.
205+ struct GlyphCleanup
206+ {
207+ FT_Glyph& glyph;
208+ ~GlyphCleanup () { FT_Done_Glyph (glyph); }
209+ } cleanup{glyph};
210+
204211 if (glyph->format != FT_GLYPH_FORMAT_BITMAP )
205212 {
206213 if (FT_Error error = FT_Glyph_To_Bitmap (&glyph, textRenderMOde, nullptr , true ); error != FT_Err_Ok)
@@ -288,16 +295,16 @@ namespace FreeType
288295 )
289296 {
290297 using namespace std ;
291- const string_type text = textCreateParams.text ;
292- const string_type& fontPath = textCreateParams.fontPath ;
293- const uint16_t fontSize = textCreateParams.fontSize ;
294- const uint32_t OutlineWidth = textCreateParams.outlineWidth ;
295- const LLUtils::Color outlineColor = textCreateParams.outlineColor ;
298+ const string_type& text = textCreateParams.text ;
299+ const string_type& fontPath = textCreateParams.fontPath ;
300+ const uint16_t fontSize = textCreateParams.fontSize ;
301+ const uint32_t OutlineWidth = textCreateParams.outlineWidth ;
302+ const LLUtils::Color outlineColor = textCreateParams.outlineColor ;
296303 const LLUtils::Color backgroundColor = textCreateParams.backgroundColor ;
297304
298- FT_Render_Mode textRenderMOde = FreeTypeRenderer::GetRenderMode (textCreateParams.renderMode );
305+ FT_Render_Mode textRenderMOde = FreeTypeRenderer::GetRenderMode (textCreateParams.renderMode );
299306 FT_Render_Mode outlineRenderMode = FreeTypeRenderer::GetRenderMode (textCreateParams.renderMode );
300- const bool renderOutline = OutlineWidth > 0 ;
307+ const bool renderOutline = OutlineWidth > 0 ;
301308
302309 if (textRenderMOde == FT_Render_Mode::FT_RENDER_MODE_LCD && renderOutline == true )
303310 textRenderMOde = FT_Render_Mode::FT_RENDER_MODE_NORMAL ;
@@ -311,17 +318,12 @@ namespace FreeType
311318
312319 font->SetSize (fontSize, textCreateParams.DPIx , textCreateParams.DPIy );
313320
314- TextMesureParams params;
315- params.createParams = textCreateParams;
316-
317321 TextMetrics metrics;
318322 if (in_metrics == nullptr )
319- MeasureText (params, metrics);
320- else
321- metrics = *in_metrics;
323+ MeasureText ({textCreateParams}, metrics);
322324
323-
324- auto & mesaureResult = metrics;
325+ // Cached measurements remain valid for this render; borrow them instead of copying their line data.
326+ const auto & mesaureResult = in_metrics != nullptr ? *in_metrics : metrics;
325327
326328 using namespace LLUtils ;
327329 const uint32_t destPixelSize = sizeof (ColorF32);
@@ -366,12 +368,11 @@ namespace FreeType
366368 dest.pixelSizeInbytes = destPixelSize;
367369 dest.rowPitch = destRowPitch;
368370
369-
370- int32_t penX = -mesaureResult. rect . LeftTop () .x ;
371- int32_t penY = -mesaureResult. rect . LeftTop () .y ;
371+ const PointI32 origin = mesaureResult. rect . GetCorner (Corner::TopLeft);
372+ int32_t penX = -origin .x ;
373+ int32_t penY = -origin .y ;
372374
373-
374- FT_Face face = font->GetFace ();
375+ FT_Face face = font->GetFace ();
375376 const auto descender = face->size ->metrics .descender >> 6 ;
376377 const uint32_t rowHeight = mesaureResult.rowHeight ;
377378
@@ -392,7 +393,7 @@ namespace FreeType
392393 {
393394 if (codepoint == L' \n ' )
394395 {
395- penX = static_cast <int >(-mesaureResult. rect . LeftTop () .x );
396+ penX = static_cast <int >(-origin .x );
396397 penY += rowHeight;
397398 continue ;
398399 }
@@ -410,10 +411,10 @@ namespace FreeType
410411 // Render outline
411412 const auto advance = face->glyph ->advance .x >> 6 ;
412413
413- if (textCreateParams.maxWidthPx > 0 && penX + advance + mesaureResult. rect . LeftTop () .x > static_cast <int >(textCreateParams.maxWidthPx ))
414+ if (textCreateParams.maxWidthPx > 0 && penX + advance + origin .x > static_cast <int >(textCreateParams.maxWidthPx ))
414415 {
415416 penY += rowHeight;
416- penX = static_cast <int >(-mesaureResult. rect . LeftTop () .x );
417+ penX = static_cast <int >(-origin .x );
417418
418419 }
419420
@@ -448,12 +449,13 @@ namespace FreeType
448449 if (glyph->format != FT_GLYPH_FORMAT_BITMAP )
449450 {
450451 if (FT_Error error = FT_Glyph_To_Bitmap (&glyph, textRenderMOde, nullptr , true ); error != FT_Err_Ok)
451- LL_EXCEPTION (LLUtils::Exception::ErrorCode::RuntimeError, " FreeType error, unable to render glyph" );
452+ LL_EXCEPTION (LLUtils::Exception::ErrorCode::RuntimeError,
453+ " FreeType error, unable to render glyph" );
452454 }
453455
454456 FT_BitmapGlyph bitmapGlyph = reinterpret_cast <FT_BitmapGlyph>(glyph);
455457 FreeTypeRenderer::BitmapProperties bitmapProperties = FreeTypeRenderer::GetBitmapGlyphProperties (bitmapGlyph->bitmap );
456- const auto textcolor = el.textColor != Color{ 0 , 0 , 0 , 0 } ? el.textColor : params. createParams .textColor ;
458+ const auto textcolor = el.textColor != Color{ 0 , 0 , 0 , 0 } ? el.textColor : textCreateParams .textColor ;
457459
458460 LLUtils::Buffer rasterizedGlyph = FreeTypeRenderer::RenderGlyphToBuffer ({ bitmapGlyph , backgroundColor, textcolor , bitmapProperties });
459461
0 commit comments