1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

Fix TextEditor crash when Font resolution fails

This commit is contained in:
attila 2025-03-31 17:49:29 +02:00 committed by Attila Szarvas
parent 9c0aeb9e00
commit 9083cd9135
3 changed files with 32 additions and 13 deletions

View file

@ -301,6 +301,12 @@ public:
*/
bool isLtr (int64 glyphIndex) const;
/* This function may fail to return an out range, even if the provided textRange falls inside
the string range used for the creation of the ShapedText object.
This is because the shaping process could fail due to insufficient glyph resolution to the
point, where it will produce zero glyphs for the provided string.
*/
void getGlyphRanges (Range<int64> textRange, std::vector<Range<int64>>& outRanges) const;
/* Returns the input codepoint index that follows the glyph in a logical sense. So for LTR text

View file

@ -889,14 +889,20 @@ TextEditor::CaretEdge TextEditor::getTextSelectionEdge (int index, Edge edge) co
auto& paragraph = paragraphIt->value;
const auto& shapedText = paragraph->getShapedText();
const auto glyphRange = std::invoke ([&]
const auto glyphRange = std::invoke ([&]() -> Range<int64>
{
std::vector<Range<int64>> g;
shapedText.getGlyphRanges (textRange - paragraph->getRange().getStart(), g);
jassert (! g.empty());
if (g.empty())
return {};
return g.front();
});
if (glyphRange.isEmpty())
return getDefaultCursorEdge();
const auto glyphsBounds = shapedText.getGlyphsBounds (glyphRange).getRectangle (0);
const auto ltr = shapedText.isLtr (glyphRange.getStart());
@ -2139,6 +2145,21 @@ bool TextEditor::isEmpty() const
return getTotalNumChars() == 0;
}
float TextEditor::getJustificationOffsetX() const
{
const auto bottomRightX = (float) getMaximumTextWidth();
if (justification.testFlags (Justification::horizontallyCentred)) return jmax (0.0f, bottomRightX * 0.5f);
if (justification.testFlags (Justification::right)) return jmax (0.0f, bottomRightX);
return 0.0f;
}
TextEditor::CaretEdge TextEditor::getDefaultCursorEdge() const
{
return { { getJustificationOffsetX(), 0.0f }, currentFont.getHeight() };
}
TextEditor::CaretEdge TextEditor::getCursorEdge (const CaretState& tempCaret) const
{
const auto visualIndex = tempCaret.getVisualIndex();
@ -2147,18 +2168,8 @@ TextEditor::CaretEdge TextEditor::getCursorEdge (const CaretState& tempCaret) co
if (getWordWrapWidth() <= 0)
return { {}, currentFont.getHeight() };
const auto getJustificationOffsetX = [&]
{
const auto bottomRightX = (float) getMaximumTextWidth();
if (justification.testFlags (Justification::horizontallyCentred)) return jmax (0.0f, bottomRightX * 0.5f);
if (justification.testFlags (Justification::right)) return jmax (0.0f, bottomRightX);
return 0.0f;
};
if (textStorage->isEmpty())
return { { getJustificationOffsetX(), 0.0f }, currentFont.getHeight() };
return getDefaultCursorEdge();
if (visualIndex == getTotalNumChars())
{

View file

@ -913,6 +913,8 @@ private:
float height{};
};
float getJustificationOffsetX() const;
CaretEdge getDefaultCursorEdge() const;
CaretEdge getTextSelectionEdge (int index, Edge edge) const;
CaretEdge getCursorEdge (const CaretState& caret) const;
void updateCaretPosition();