imtui icon indicating copy to clipboard operation
imtui copied to clipboard

Passing character info to renderer

Open dvj opened this issue 3 years ago • 2 comments

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)

dvj avatar Mar 17 '21 23:03 dvj

Ok, that is pretty clever.

I'll let you know if I get some ideas about this, but at the moment your concept seems much better than the existing one.

ggerganov avatar Mar 18 '21 19:03 ggerganov