| 3212 | } |
| 3213 | |
| 3214 | void ImFont::BuildLookupTable() |
| 3215 | { |
| 3216 | int max_codepoint = 0; |
| 3217 | for (int i = 0; i != Glyphs.Size; i++) |
| 3218 | max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); |
| 3219 | |
| 3220 | // Build lookup table |
| 3221 | IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved |
| 3222 | IndexAdvanceX.clear(); |
| 3223 | IndexLookup.clear(); |
| 3224 | DirtyLookupTables = false; |
| 3225 | memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap)); |
| 3226 | GrowIndex(max_codepoint + 1); |
| 3227 | for (int i = 0; i < Glyphs.Size; i++) |
| 3228 | { |
| 3229 | int codepoint = (int)Glyphs[i].Codepoint; |
| 3230 | IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX; |
| 3231 | IndexLookup[codepoint] = (ImWchar)i; |
| 3232 | |
| 3233 | // Mark 4K page as used |
| 3234 | const int page_n = codepoint / 4096; |
| 3235 | Used4kPagesMap[page_n >> 3] |= 1 << (page_n & 7); |
| 3236 | } |
| 3237 | |
| 3238 | // Create a glyph to handle TAB |
| 3239 | // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) |
| 3240 | if (FindGlyph((ImWchar)' ')) |
| 3241 | { |
| 3242 | if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times (FIXME: Flaky) |
| 3243 | Glyphs.resize(Glyphs.Size + 1); |
| 3244 | ImFontGlyph& tab_glyph = Glyphs.back(); |
| 3245 | tab_glyph = *FindGlyph((ImWchar)' '); |
| 3246 | tab_glyph.Codepoint = '\t'; |
| 3247 | tab_glyph.AdvanceX *= IM_TABSIZE; |
| 3248 | IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; |
| 3249 | IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size - 1); |
| 3250 | } |
| 3251 | |
| 3252 | // Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons) |
| 3253 | SetGlyphVisible((ImWchar)' ', false); |
| 3254 | SetGlyphVisible((ImWchar)'\t', false); |
| 3255 | |
| 3256 | // Setup Fallback character |
| 3257 | const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' }; |
| 3258 | FallbackGlyph = FindGlyphNoFallback(FallbackChar); |
| 3259 | if (FallbackGlyph == NULL) |
| 3260 | { |
| 3261 | FallbackChar = FindFirstExistingGlyph(this, fallback_chars, IM_ARRAYSIZE(fallback_chars)); |
| 3262 | FallbackGlyph = FindGlyphNoFallback(FallbackChar); |
| 3263 | if (FallbackGlyph == NULL) |
| 3264 | { |
| 3265 | FallbackGlyph = &Glyphs.back(); |
| 3266 | FallbackChar = (ImWchar)FallbackGlyph->Codepoint; |
| 3267 | } |
| 3268 | } |
| 3269 | FallbackAdvanceX = FallbackGlyph->AdvanceX; |
| 3270 | for (int i = 0; i < max_codepoint + 1; i++) |
| 3271 | if (IndexAdvanceX[i] < 0.0f) |
no test coverage detected