mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	ImFontAtlas: some more optimisations / cleanup.
This commit is contained in:
		
							
								
								
									
										62
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -6307,7 +6307,8 @@ struct ImFontAtlas::ImFontAtlasData | ||||
|     // Temporary Build Data | ||||
|     stbtt_fontinfo      FontInfo; | ||||
|     stbrp_rect*         Rects; | ||||
|     ImVector<stbtt_pack_range>  Ranges; | ||||
|     stbtt_pack_range*   Ranges; | ||||
|     int                 RangesCount; | ||||
| }; | ||||
|  | ||||
| ImFontAtlas::ImFontAtlas() | ||||
| @@ -6468,6 +6469,7 @@ bool    ImFontAtlas::Build() | ||||
|  | ||||
|     // Initialize font information early (so we can error without any cleanup) + count glyphs | ||||
|     int total_glyph_count = 0; | ||||
|     int total_glyph_range_count = 0; | ||||
|     for (size_t input_i = 0; input_i < InputData.size(); input_i++) | ||||
|     { | ||||
|         ImFontAtlasData& data = *InputData[input_i]; | ||||
| @@ -6480,7 +6482,10 @@ bool    ImFontAtlas::Build() | ||||
|         if (!data.GlyphRanges) | ||||
|             data.GlyphRanges = GetGlyphRangesDefault(); | ||||
|         for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) | ||||
|         { | ||||
|             total_glyph_count += (in_range[1] - in_range[0]) + 1; | ||||
|             total_glyph_range_count++; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Start packing | ||||
| @@ -6499,13 +6504,13 @@ bool    ImFontAtlas::Build() | ||||
|     stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rect, 1); | ||||
|     TexExtraDataPos = ImVec2(extra_rect.x, extra_rect.y); | ||||
|  | ||||
|     // Allocate packing character data and flag as non-packed (x0=y0=x1=y1=0) | ||||
|     stbtt_packedchar* packed_chardata = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); | ||||
|     int packed_chardata_n = 0; | ||||
|     memset(packed_chardata, 0, total_glyph_count * sizeof(stbtt_packedchar)); | ||||
|  | ||||
|     stbrp_rect* rectdata = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); | ||||
|     int rectdata_n = 0; | ||||
|     // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) | ||||
|     int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; | ||||
|     stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); | ||||
|     stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); | ||||
|     stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_glyph_range_count * sizeof(stbtt_pack_range)); | ||||
|     memset(buf_packedchars, 0, total_glyph_count * sizeof(stbtt_packedchar)); | ||||
|     memset(buf_ranges, 0, total_glyph_range_count * sizeof(stbtt_pack_range)); | ||||
|  | ||||
|     // First pass: pack all glyphs (no rendering at this point, we are working with glyph sizes only) | ||||
|     int tex_height = extra_rect.y + extra_rect.h; | ||||
| @@ -6521,22 +6526,24 @@ bool    ImFontAtlas::Build() | ||||
|             glyph_count += (in_range[1] - in_range[0]) + 1; | ||||
|             glyph_ranges_count++; | ||||
|         } | ||||
|         data.Ranges.resize(glyph_ranges_count); | ||||
|         for (size_t i = 0; i < data.Ranges.size(); i++) | ||||
|         data.Ranges = buf_ranges + buf_ranges_n; | ||||
|         data.RangesCount = glyph_ranges_count; | ||||
|         buf_ranges_n += glyph_ranges_count; | ||||
|         for (size_t i = 0; i < glyph_ranges_count; i++) | ||||
|         { | ||||
|             const ImWchar* in_range = &data.GlyphRanges[i * 2]; | ||||
|             stbtt_pack_range& range = data.Ranges[i]; | ||||
|             range.font_size = data.SizePixels; | ||||
|             const ImWchar* in_range = &data.GlyphRanges[i * 2]; | ||||
|             range.first_unicode_char_in_range = in_range[0]; | ||||
|             range.num_chars_in_range = (in_range[1] - in_range[0]) + 1; | ||||
|             range.chardata_for_range = packed_chardata + packed_chardata_n; | ||||
|             packed_chardata_n += range.num_chars_in_range; | ||||
|             range.chardata_for_range = buf_packedchars + buf_packedchars_n; | ||||
|             buf_packedchars_n += range.num_chars_in_range; | ||||
|         } | ||||
|  | ||||
|         // Pack | ||||
|         data.Rects = rectdata + rectdata_n; | ||||
|         rectdata_n += glyph_count; | ||||
|         const int n = stbtt_PackFontRangesGatherRects(&spc, &data.FontInfo, data.Ranges.begin(), data.Ranges.size(), data.Rects); | ||||
|         data.Rects = buf_rects + buf_rects_n; | ||||
|         buf_rects_n += glyph_count; | ||||
|         const int n = stbtt_PackFontRangesGatherRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects); | ||||
|         stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n); | ||||
|  | ||||
|         // Extend texture height | ||||
| @@ -6544,11 +6551,13 @@ bool    ImFontAtlas::Build() | ||||
|             if (data.Rects[i].was_packed) | ||||
|                 tex_height = ImMax(tex_height, data.Rects[i].y + data.Rects[i].h); | ||||
|     } | ||||
|     IM_ASSERT(packed_chardata_n == total_glyph_count); | ||||
|     IM_ASSERT(buf_rects_n == total_glyph_count); | ||||
|     IM_ASSERT(buf_packedchars_n == total_glyph_count); | ||||
|     IM_ASSERT(buf_ranges_n == total_glyph_range_count); | ||||
|  | ||||
|     // Create texture | ||||
|     TexHeight = ImUpperPowerOfTwo(tex_height); | ||||
|     TexPixelsAlpha8 = (unsigned char*)ImGui::MemRealloc(TexPixelsAlpha8, TexWidth * TexHeight); | ||||
|     TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight); | ||||
|     memset(TexPixelsAlpha8, 0, TexWidth * TexHeight); | ||||
|     spc.pixels = TexPixelsAlpha8; | ||||
|     spc.height = TexHeight; | ||||
| @@ -6557,14 +6566,14 @@ bool    ImFontAtlas::Build() | ||||
|     for (size_t input_i = 0; input_i < InputData.size(); input_i++) | ||||
|     { | ||||
|         ImFontAtlasData& data = *InputData[input_i]; | ||||
|         ret = stbtt_PackFontRangesRenderIntoRects(&spc, &data.FontInfo, data.Ranges.begin(), data.Ranges.size(), data.Rects); | ||||
|         ret = stbtt_PackFontRangesRenderIntoRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects); | ||||
|         data.Rects = NULL; | ||||
|     } | ||||
|  | ||||
|     // End packing | ||||
|     stbtt_PackEnd(&spc); | ||||
|     ImGui::MemFree(rectdata); | ||||
|     rectdata = NULL; | ||||
|     ImGui::MemFree(buf_rects); | ||||
|     buf_rects = NULL; | ||||
|  | ||||
|     // Third pass: setup ImFont and glyphs for runtime | ||||
|     for (size_t input_i = 0; input_i < InputData.size(); input_i++) | ||||
| @@ -6580,7 +6589,7 @@ bool    ImFontAtlas::Build() | ||||
|         const float uv_scale_x = 1.0f / TexWidth; | ||||
|         const float uv_scale_y = 1.0f / TexHeight; | ||||
|         const int character_spacing_x = 1; | ||||
|         for (size_t i = 0; i < data.Ranges.size(); i++) | ||||
|         for (int i = 0; i < data.RangesCount; i++) | ||||
|         { | ||||
|             stbtt_pack_range& range = data.Ranges[i]; | ||||
|             for (int char_idx = 0; char_idx < range.num_chars_in_range; char_idx += 1) | ||||
| @@ -6606,15 +6615,14 @@ bool    ImFontAtlas::Build() | ||||
|         } | ||||
|  | ||||
|         data.OutFont->BuildLookupTable(); | ||||
|  | ||||
|         // Cleanup temporaries | ||||
|         data.Ranges.clear(); | ||||
|     } | ||||
|  | ||||
|     // Cleanup temporaries | ||||
|     ImGui::MemFree(buf_packedchars); | ||||
|     ImGui::MemFree(buf_ranges); | ||||
|     buf_packedchars = NULL; | ||||
|     buf_ranges = NULL; | ||||
|     ClearInputData(); | ||||
|     ImGui::MemFree(packed_chardata); | ||||
|     packed_chardata = NULL; | ||||
|  | ||||
|     // Draw white pixel into texture and make UV points to it | ||||
|     TexPixelsAlpha8[0] = TexPixelsAlpha8[1] = TexPixelsAlpha8[TexWidth+0] = TexPixelsAlpha8[TexWidth+1] = 0xFF; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user