///////////////////////////////////////////////////////
| 622 | |
| 623 | //////////////////////////////////////////////////////////// |
| 624 | Vector2f Text::findCharacterPos(std::size_t index) const |
| 625 | { |
| 626 | ensureGeometryUpdate(); |
| 627 | |
| 628 | // Adjust the index if it's out of range |
| 629 | index = std::min(index, m_glyphs.size()); |
| 630 | |
| 631 | // Precompute the variables needed by the algorithm |
| 632 | const bool isBold = m_style & Bold; |
| 633 | const float whitespaceWidth = m_font->getGlyph(U' ', m_characterSize, isBold).advance; |
| 634 | const float letterSpacing = (whitespaceWidth / 3.0f) * (m_letterSpacingFactor - 1.0f); |
| 635 | const float lineSpacing = m_font->getLineSpacing(m_characterSize) * m_lineSpacingFactor; |
| 636 | |
| 637 | // Special handling for newlines: |
| 638 | // The old shaping implementation placed newline characters |
| 639 | // at the start of the new line that they create |
| 640 | // The new implementation places them at the end of the previous line |
| 641 | // Placing them at the end of the previous line is normally what is expected |
| 642 | // since the cursor is rendered before the glyph whose location marks the |
| 643 | // location at which new characters will be inserted into the text |
| 644 | // We provide a workaround for the old behavior until findCharacterPos can be removed |
| 645 | |
| 646 | if (m_glyphs.empty()) |
| 647 | { |
| 648 | // Get the position of the Text itself in global coordinates |
| 649 | return getTransform().transformPoint({}); |
| 650 | } |
| 651 | |
| 652 | if (index == m_glyphs.size()) |
| 653 | { |
| 654 | // Return the position of the last glyph + its advance in global coordinates |
| 655 | const auto& lastGlyph = m_glyphs.back(); |
| 656 | |
| 657 | // Newline, past-the-end |
| 658 | if (m_string[m_string.getSize() - 1] == '\n') |
| 659 | return getTransform().transformPoint( |
| 660 | Vector2f{0.0f, lastGlyph.position.y + lineSpacing - static_cast<float>(m_characterSize)}); |
| 661 | |
| 662 | return getTransform().transformPoint( |
| 663 | lastGlyph.position + Vector2f{lastGlyph.glyph.advance + letterSpacing, -static_cast<float>(m_characterSize)}); |
| 664 | } |
| 665 | |
| 666 | // Newline, not past-the-end |
| 667 | if (m_string[index] == '\n') |
| 668 | return getTransform().transformPoint( |
| 669 | Vector2f{0.0f, m_glyphs[index].position.y + lineSpacing - static_cast<float>(m_characterSize)}); |
| 670 | |
| 671 | return getTransform().transformPoint(m_glyphs[index].position - Vector2f{0.0f, static_cast<float>(m_characterSize)}); |
| 672 | } |
| 673 | |
| 674 | |
| 675 | //////////////////////////////////////////////////////////// |
no test coverage detected