| 3516 | } |
| 3517 | |
| 3518 | ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const |
| 3519 | { |
| 3520 | if (!text_end) |
| 3521 | text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. |
| 3522 | |
| 3523 | const float line_height = size; |
| 3524 | const float scale = size / FontSize; |
| 3525 | |
| 3526 | ImVec2 text_size = ImVec2(0, 0); |
| 3527 | float line_width = 0.0f; |
| 3528 | |
| 3529 | const bool word_wrap_enabled = (wrap_width > 0.0f); |
| 3530 | const char* word_wrap_eol = NULL; |
| 3531 | |
| 3532 | const char* s = text_begin; |
| 3533 | while (s < text_end) |
| 3534 | { |
| 3535 | if (word_wrap_enabled) |
| 3536 | { |
| 3537 | // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. |
| 3538 | if (!word_wrap_eol) |
| 3539 | word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); |
| 3540 | |
| 3541 | if (s >= word_wrap_eol) |
| 3542 | { |
| 3543 | if (text_size.x < line_width) |
| 3544 | text_size.x = line_width; |
| 3545 | text_size.y += line_height; |
| 3546 | line_width = 0.0f; |
| 3547 | word_wrap_eol = NULL; |
| 3548 | s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks |
| 3549 | continue; |
| 3550 | } |
| 3551 | } |
| 3552 | |
| 3553 | // Decode and advance source |
| 3554 | const char* prev_s = s; |
| 3555 | unsigned int c = (unsigned int)*s; |
| 3556 | if (c < 0x80) |
| 3557 | s += 1; |
| 3558 | else |
| 3559 | s += ImTextCharFromUtf8(&c, s, text_end); |
| 3560 | |
| 3561 | if (c < 32) |
| 3562 | { |
| 3563 | if (c == '\n') |
| 3564 | { |
| 3565 | text_size.x = ImMax(text_size.x, line_width); |
| 3566 | text_size.y += line_height; |
| 3567 | line_width = 0.0f; |
| 3568 | continue; |
| 3569 | } |
| 3570 | if (c == '\r') |
| 3571 | continue; |
| 3572 | } |
| 3573 | |
| 3574 | const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX) * scale; |
| 3575 | if (line_width + char_width >= max_width) |
no test coverage detected