Currently, imtui uses a modified ImFont::RenderText function where it inserts the ascii value of the character to be rendered in the alpha channel of the color (ImDrawVert.col). While this makes imtui possible, it requires a modification to imgui itself achieve, which makes long term maintenance an issue.
Here is a proposed way to pass the character values by using the coordinates in the font texture instead. Proof of concept code below.
std::unordered_map<int, uint8_t> character_lookup; // <-- needs persistence: global, class var, function param, etc.
auto io = ImGui::GetIO();
// tell imgui we have lots of 1x1 custom character glyphs in the texture
int ids[255]; //store the returned id's
for (int i = 1;i<255;i++) {
ids[i] = io.Fonts->AddCustomRectFontGlyph(font, i, 1,1,1);
}
// Build atlas [existing code block]
unsigned char* tex_pixels = NULL;
int tex_w, tex_h;
ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h);
// store the texture coordinates in a hashmap
for (int i = 1;i<255;i++) {
//lookup the id we got, and get the texture coordinates (in integer pixel values)
const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(ids[i]);
// store the texture index with the character value
character_lookup[rect->X + rect->Y*rect->Width] = i;
}
Then, in the render function, once it's determined this is a textured 1x1 glyph, read the position in the texture to get the character index:
// get the texture scale (could be stored)
ImVec2 font_scale = ImGuiIO().Fonts->TexUvScale;
// uv coords are [0..1], remap to integer values that match the rect we got when storing
int index = uv0.x/font_scale.x+uv0.y/font_scale.y;
auto char_code = character_lookup[index];
cell |= char_code;
I've tested this and it works without issue, with some error handling, etc. Posting here for input and ideas before making a PR.
I believe many of the other changes in the local fork of imgui can be resolved when the work on "style V2" commences. (See, for example, https://github.com/ocornut/imgui/issues/2017)
Currently, imtui uses a modified
ImFont::RenderText
function where it inserts the ascii value of the character to be rendered in the alpha channel of the color (ImDrawVert.col
). While this makes imtui possible, it requires a modification to imgui itself achieve, which makes long term maintenance an issue.Here is a proposed way to pass the character values by using the coordinates in the font texture instead. Proof of concept code below.
Then, in the render function, once it's determined this is a textured 1x1 glyph, read the position in the texture to get the character index:
I've tested this and it works without issue, with some error handling, etc. Posting here for input and ideas before making a PR.
I believe many of the other changes in the local fork of imgui can be resolved when the work on "style V2" commences. (See, for example, https://github.com/ocornut/imgui/issues/2017)