| 3508 | } |
| 3509 | |
| 3510 | static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas) |
| 3511 | { |
| 3512 | if (atlas->Flags & ImFontAtlasFlags_NoBakedLines) |
| 3513 | return; |
| 3514 | |
| 3515 | // Pack and store identifier so we can refresh UV coordinates on texture resize. |
| 3516 | ImTextureData* tex = atlas->TexData; |
| 3517 | ImFontAtlasBuilder* builder = atlas->Builder; |
| 3518 | |
| 3519 | ImFontAtlasRect r; |
| 3520 | bool add_and_draw = atlas->GetCustomRect(builder->PackIdLinesTexData, &r) == false; |
| 3521 | if (add_and_draw) |
| 3522 | { |
| 3523 | ImVec2i pack_size = ImVec2i(IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 2, IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1); |
| 3524 | builder->PackIdLinesTexData = atlas->AddCustomRect(pack_size.x, pack_size.y, &r); |
| 3525 | IM_ASSERT(builder->PackIdLinesTexData != ImFontAtlasRectId_Invalid); |
| 3526 | } |
| 3527 | |
| 3528 | // Register texture region for thick lines |
| 3529 | // The +2 here is to give space for the end caps, whilst height +1 is to accommodate the fact we have a zero-width row |
| 3530 | // This generates a triangular shape in the texture, with the various line widths stacked on top of each other to allow interpolation between them |
| 3531 | for (int n = 0; n < IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row |
| 3532 | { |
| 3533 | // Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle |
| 3534 | const int y = n; |
| 3535 | const int line_width = n; |
| 3536 | const int pad_left = (r.w - line_width) / 2; |
| 3537 | const int pad_right = r.w - (pad_left + line_width); |
| 3538 | IM_ASSERT(pad_left + line_width + pad_right == r.w && y < r.h); // Make sure we're inside the texture bounds before we start writing pixels |
| 3539 | |
| 3540 | // Write each slice |
| 3541 | if (add_and_draw && tex->Format == ImTextureFormat_Alpha8) |
| 3542 | { |
| 3543 | ImU8* write_ptr = (ImU8*)tex->GetPixelsAt(r.x, r.y + y); |
| 3544 | for (int i = 0; i < pad_left; i++) |
| 3545 | *(write_ptr + i) = 0x00; |
| 3546 | |
| 3547 | for (int i = 0; i < line_width; i++) |
| 3548 | *(write_ptr + pad_left + i) = 0xFF; |
| 3549 | |
| 3550 | for (int i = 0; i < pad_right; i++) |
| 3551 | *(write_ptr + pad_left + line_width + i) = 0x00; |
| 3552 | } |
| 3553 | else if (add_and_draw && tex->Format == ImTextureFormat_RGBA32) |
| 3554 | { |
| 3555 | ImU32* write_ptr = (ImU32*)(void*)tex->GetPixelsAt(r.x, r.y + y); |
| 3556 | for (int i = 0; i < pad_left; i++) |
| 3557 | *(write_ptr + i) = IM_COL32(255, 255, 255, 0); |
| 3558 | |
| 3559 | for (int i = 0; i < line_width; i++) |
| 3560 | *(write_ptr + pad_left + i) = IM_COL32_WHITE; |
| 3561 | |
| 3562 | for (int i = 0; i < pad_right; i++) |
| 3563 | *(write_ptr + pad_left + line_width + i) = IM_COL32(255, 255, 255, 0); |
| 3564 | } |
| 3565 | |
| 3566 | // Refresh UV coordinates |
| 3567 | ImVec2 uv0 = ImVec2((float)(r.x + pad_left - 1), (float)(r.y + y)) * atlas->TexUvScale; |
no test coverage detected