mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	InputText: Fixed password fields displaying ASCII spaces as blanks. Fixed non-ASCII space occasionally creating unnecessary empty polygons. (#2149, #515)
This commit is contained in:
		| @@ -38,6 +38,9 @@ Other Changes: | ||||
|  | ||||
| - ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced | ||||
|   by default for standalone ColorButton. | ||||
| - InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' | ||||
|   glyph. (#2149, #515) | ||||
| - Font: Fixed non-ASCII space occasionally creating unnecessary empty polygons. | ||||
| - Demo: Added a black and white gradient to Demo>Examples>Custom Rendering. | ||||
| - Backends: SDL: Added ImGui_ImplSDL2_InitForMetal() for API consistency (even though the function | ||||
|   currently does nothing). | ||||
|   | ||||
							
								
								
									
										6
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -2068,9 +2068,12 @@ struct ImFontConfig | ||||
|     IMGUI_API ImFontConfig(); | ||||
| }; | ||||
|  | ||||
| // Hold rendering data for one glyph. | ||||
| // (Note: some language parsers may fail to convert the 31+1 bitfield members, in this case maybe drop store a single u32 or we can rework this) | ||||
| struct ImFontGlyph | ||||
| { | ||||
|     ImWchar         Codepoint;          // 0x0000..0xFFFF | ||||
|     unsigned int    Codepoint : 31;     // 0x0000..0xFFFF | ||||
|     unsigned int    Visible : 1;        // Flag to allow early out when rendering | ||||
|     float           AdvanceX;           // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) | ||||
|     float           X0, Y0, X1, Y1;     // Glyph corners | ||||
|     float           U0, V0, U1, V1;     // Texture coordinates | ||||
| @@ -2265,6 +2268,7 @@ struct ImFont | ||||
|     IMGUI_API void              GrowIndex(int new_size); | ||||
|     IMGUI_API void              AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); | ||||
|     IMGUI_API void              AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. | ||||
|     IMGUI_API void              SetGlyphVisible(ImWchar c, bool visible); | ||||
|     IMGUI_API void              SetFallbackChar(ImWchar c); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1040,11 +1040,11 @@ static void ShowDemoWindowWidgets() | ||||
|             static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); | ||||
|  | ||||
|             ImGui::Text("Password input"); | ||||
|             static char bufpass[64] = "password123"; | ||||
|             ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); | ||||
|             static char password[64] = "password123"; | ||||
|             ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); | ||||
|             ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); | ||||
|             ImGui::InputTextWithHint("password (w/ hint)", "<password>", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); | ||||
|             ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); | ||||
|             ImGui::InputTextWithHint("password (w/ hint)", "<password>", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); | ||||
|             ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_CharsNoBlank); | ||||
|             ImGui::TreePop(); | ||||
|         } | ||||
|  | ||||
| @@ -3465,6 +3465,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) | ||||
|                                         ImGui::BeginTooltip(); | ||||
|                                         ImGui::Text("Codepoint: U+%04X", base + n); | ||||
|                                         ImGui::Separator(); | ||||
|                                         ImGui::Text("Visible: %d", glyph->Visible); | ||||
|                                         ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX); | ||||
|                                         ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); | ||||
|                                         ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); | ||||
|   | ||||
| @@ -2622,6 +2622,7 @@ void ImFont::BuildLookupTable() | ||||
|     for (int i = 0; i != Glyphs.Size; i++) | ||||
|         max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); | ||||
|  | ||||
|     // Build lookup table | ||||
|     IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved | ||||
|     IndexAdvanceX.clear(); | ||||
|     IndexLookup.clear(); | ||||
| @@ -2638,7 +2639,7 @@ void ImFont::BuildLookupTable() | ||||
|     // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) | ||||
|     if (FindGlyph((ImWchar)' ')) | ||||
|     { | ||||
|         if (Glyphs.back().Codepoint != '\t')   // So we can call this function multiple times | ||||
|         if (Glyphs.back().Codepoint != '\t')   // So we can call this function multiple times (FIXME: Flaky) | ||||
|             Glyphs.resize(Glyphs.Size + 1); | ||||
|         ImFontGlyph& tab_glyph = Glyphs.back(); | ||||
|         tab_glyph = *FindGlyph((ImWchar)' '); | ||||
| @@ -2648,6 +2649,11 @@ void ImFont::BuildLookupTable() | ||||
|         IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size-1); | ||||
|     } | ||||
|  | ||||
|     // Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons) | ||||
|     SetGlyphVisible((ImWchar)' ', false); | ||||
|     SetGlyphVisible((ImWchar)'\t', false); | ||||
|  | ||||
|     // Setup fall-backs | ||||
|     FallbackGlyph = FindGlyphNoFallback(FallbackChar); | ||||
|     FallbackAdvanceX = FallbackGlyph ? FallbackGlyph->AdvanceX : 0.0f; | ||||
|     for (int i = 0; i < max_codepoint + 1; i++) | ||||
| @@ -2655,6 +2661,12 @@ void ImFont::BuildLookupTable() | ||||
|             IndexAdvanceX[i] = FallbackAdvanceX; | ||||
| } | ||||
|  | ||||
| void ImFont::SetGlyphVisible(ImWchar c, bool visible) | ||||
| { | ||||
|     if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)c)) | ||||
|         glyph->Visible = visible ? 1 : 0; | ||||
| } | ||||
|  | ||||
| void ImFont::SetFallbackChar(ImWchar c) | ||||
| { | ||||
|     FallbackChar = c; | ||||
| @@ -2676,7 +2688,8 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, | ||||
| { | ||||
|     Glyphs.resize(Glyphs.Size + 1); | ||||
|     ImFontGlyph& glyph = Glyphs.back(); | ||||
|     glyph.Codepoint = (ImWchar)codepoint; | ||||
|     glyph.Codepoint = (unsigned int)codepoint; | ||||
|     glyph.Visible = (x0 != x1) && (y0 != y1); | ||||
|     glyph.X0 = x0; | ||||
|     glyph.Y0 = y0; | ||||
|     glyph.X1 = x1; | ||||
| @@ -2925,16 +2938,14 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons | ||||
|  | ||||
| void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const | ||||
| { | ||||
|     if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. | ||||
|     const ImFontGlyph* glyph = FindGlyph(c); | ||||
|     if (!glyph || !glyph->Visible) | ||||
|         return; | ||||
|     if (const ImFontGlyph* glyph = FindGlyph(c)) | ||||
|     { | ||||
|     float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; | ||||
|     pos.x = IM_FLOOR(pos.x + DisplayOffset.x); | ||||
|     pos.y = IM_FLOOR(pos.y + DisplayOffset.y); | ||||
|     draw_list->PrimReserve(6, 4); | ||||
|     draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const | ||||
| @@ -3047,13 +3058,12 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col | ||||
|                 continue; | ||||
|         } | ||||
|  | ||||
|         float char_width = 0.0f; | ||||
|         if (const ImFontGlyph* glyph = FindGlyph((ImWchar)c)) | ||||
|         { | ||||
|             char_width = glyph->AdvanceX * scale; | ||||
|         const ImFontGlyph* glyph = FindGlyph((ImWchar)c); | ||||
|         if (glyph == NULL) | ||||
|             continue; | ||||
|  | ||||
|             // Arbitrarily assume that both space and tabs are empty glyphs as an optimization | ||||
|             if (c != ' ' && c != '\t') | ||||
|         float char_width = glyph->AdvanceX * scale; | ||||
|         if (glyph->Visible) | ||||
|         { | ||||
|             // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w | ||||
|             float x1 = x + glyph->X0 * scale; | ||||
| @@ -3112,8 +3122,6 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         } | ||||
|  | ||||
|         x += char_width; | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 omar
					omar