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:
parent
9c0aeb9e00
commit
9083cd9135
3 changed files with 32 additions and 13 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue