mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
TextEditor: Fix setLineSpacing
Applies the previously missed line spacing value of the TextEditor. The changes in JustifiedText fix calculating the vertical position of the first line for the case where ShapedTextOptions has the following settings: isBaselineAtZero() == false, getHeight().has_value() == false getLeading() > 1.0f This case however is only triggered by the TextEditor, as with all functions in GlyphArrangement at least one setting is different.
This commit is contained in:
parent
e23969f3ce
commit
d2d5e9bdd2
3 changed files with 19 additions and 15 deletions
|
|
@ -200,12 +200,12 @@ struct LineInfo
|
||||||
static float getCrossAxisStartingAnchor (Justification justification,
|
static float getCrossAxisStartingAnchor (Justification justification,
|
||||||
Span<const LineInfo> lineInfos,
|
Span<const LineInfo> lineInfos,
|
||||||
std::optional<float> height,
|
std::optional<float> height,
|
||||||
float leadingInHeight)
|
float leading)
|
||||||
{
|
{
|
||||||
if (lineInfos.empty())
|
if (lineInfos.empty())
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
const auto minimumTop = lineInfos.front().maxAscent + lineInfos.front().lineHeight * leadingInHeight;
|
const auto minimumTop = lineInfos.front().maxAscent * leading;
|
||||||
|
|
||||||
if (! height.has_value())
|
if (! height.has_value())
|
||||||
return minimumTop;
|
return minimumTop;
|
||||||
|
|
@ -213,15 +213,14 @@ static float getCrossAxisStartingAnchor (Justification justification,
|
||||||
const auto textHeight = std::accumulate (lineInfos.begin(),
|
const auto textHeight = std::accumulate (lineInfos.begin(),
|
||||||
lineInfos.end(),
|
lineInfos.end(),
|
||||||
0.0f,
|
0.0f,
|
||||||
[] (auto acc, const auto info) { return acc + info.lineHeight; });
|
[leading] (auto acc, const auto info) { return acc + info.lineHeight * leading; });
|
||||||
|
|
||||||
if (justification.testFlags (Justification::verticallyCentred))
|
if (justification.testFlags (Justification::verticallyCentred))
|
||||||
return (*height - textHeight) / 2.0f + lineInfos.front().maxAscent;
|
return (*height - textHeight) / 2.0f + lineInfos.front().maxAscent;
|
||||||
|
|
||||||
if (justification.testFlags (Justification::bottom))
|
if (justification.testFlags (Justification::bottom))
|
||||||
{
|
{
|
||||||
const auto bottomLeading = 0.5f * lineInfos.back().lineHeight * leadingInHeight;
|
return *height - textHeight + lineInfos.front().maxAscent * leading;
|
||||||
return *height - textHeight - bottomLeading + lineInfos.front().maxAscent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return minimumTop;
|
return minimumTop;
|
||||||
|
|
@ -230,8 +229,6 @@ static float getCrossAxisStartingAnchor (Justification justification,
|
||||||
JustifiedText::JustifiedText (const SimpleShapedText* t, const ShapedTextOptions& options)
|
JustifiedText::JustifiedText (const SimpleShapedText* t, const ShapedTextOptions& options)
|
||||||
: shapedText (*t)
|
: shapedText (*t)
|
||||||
{
|
{
|
||||||
const auto leading = options.getLeading() - 1.0f;
|
|
||||||
|
|
||||||
std::vector<LineInfo> lineInfos;
|
std::vector<LineInfo> lineInfos;
|
||||||
|
|
||||||
for (const auto [range, lineNumber] : shapedText.getLineNumbersForGlyphRanges())
|
for (const auto [range, lineNumber] : shapedText.getLineNumbersForGlyphRanges())
|
||||||
|
|
@ -285,7 +282,7 @@ JustifiedText::JustifiedText (const SimpleShapedText* t, const ShapedTextOptions
|
||||||
: getCrossAxisStartingAnchor (options.getJustification(),
|
: getCrossAxisStartingAnchor (options.getJustification(),
|
||||||
lineInfos,
|
lineInfos,
|
||||||
options.getHeight(),
|
options.getHeight(),
|
||||||
leading);
|
options.getLeading());
|
||||||
|
|
||||||
detail::Ranges::Operations ops;
|
detail::Ranges::Operations ops;
|
||||||
|
|
||||||
|
|
@ -297,16 +294,16 @@ JustifiedText::JustifiedText (const SimpleShapedText* t, const ShapedTextOptions
|
||||||
const auto range = lineNumber.range;
|
const auto range = lineNumber.range;
|
||||||
|
|
||||||
const auto maxDescent = lineInfo.lineHeight - lineInfo.maxAscent;
|
const auto maxDescent = lineInfo.lineHeight - lineInfo.maxAscent;
|
||||||
const auto nextLineTop = baseline + (1.0f + leading) * maxDescent + options.getAdditiveLineSpacing();
|
const auto nextLineTop = baseline + options.getLeading() * maxDescent + options.getAdditiveLineSpacing();
|
||||||
|
|
||||||
if (! top.has_value())
|
if (! top.has_value())
|
||||||
top = baseline - (1.0f + leading) * lineInfo.maxAscent;
|
top = baseline - options.getLeading() * lineInfo.maxAscent;
|
||||||
|
|
||||||
lineMetricsForGlyphRange.set (range,
|
lineMetricsForGlyphRange.set (range,
|
||||||
{ lineNumber.value,
|
{ lineNumber.value,
|
||||||
{ lineInfo.mainAxisLineAlignment.anchor, baseline },
|
{ lineInfo.mainAxisLineAlignment.anchor, baseline },
|
||||||
lineInfo.maxAscent,
|
lineInfo.maxAscent * options.getLeading(),
|
||||||
lineInfo.lineHeight - lineInfo.maxAscent,
|
(lineInfo.lineHeight - lineInfo.maxAscent) * options.getLeading(),
|
||||||
lineInfo.mainAxisLineAlignment.effectiveLineLength
|
lineInfo.mainAxisLineAlignment.effectiveLineLength
|
||||||
+ lineInfo.mainAxisLineAlignment.extraWhitespaceAdvance,
|
+ lineInfo.mainAxisLineAlignment.extraWhitespaceAdvance,
|
||||||
*top,
|
*top,
|
||||||
|
|
@ -324,7 +321,7 @@ JustifiedText::JustifiedText (const SimpleShapedText* t, const ShapedTextOptions
|
||||||
ops.clear();
|
ops.clear();
|
||||||
|
|
||||||
const auto nextLineMaxAscent = lineIndex < (int) lineInfos.size() - 1 ? lineInfos[(size_t) lineIndex + 1].maxAscent : 0.0f;
|
const auto nextLineMaxAscent = lineIndex < (int) lineInfos.size() - 1 ? lineInfos[(size_t) lineIndex + 1].maxAscent : 0.0f;
|
||||||
baseline = nextLineTop + (1.0f + leading) * nextLineMaxAscent;
|
baseline = nextLineTop + options.getLeading() * nextLineMaxAscent;
|
||||||
top = nextLineTop;
|
top = nextLineTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,12 @@ void TextEditor::setJustification (Justification j)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditor::setLineSpacing (float newLineSpacing) noexcept
|
||||||
|
{
|
||||||
|
lineSpacing = jmax (1.0f, newLineSpacing);
|
||||||
|
updateBaseShapedTextOptions();
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void TextEditor::setFont (const Font& newFont)
|
void TextEditor::setFont (const Font& newFont)
|
||||||
{
|
{
|
||||||
|
|
@ -924,7 +930,8 @@ TextEditor::CaretEdge TextEditor::getTextSelectionEdge (int index, Edge edge) co
|
||||||
void TextEditor::updateBaseShapedTextOptions()
|
void TextEditor::updateBaseShapedTextOptions()
|
||||||
{
|
{
|
||||||
auto options = detail::ShapedText::Options{}.withTrailingWhitespacesShouldFit (true)
|
auto options = detail::ShapedText::Options{}.withTrailingWhitespacesShouldFit (true)
|
||||||
.withJustification (getJustificationType().getOnlyHorizontalFlags());
|
.withJustification (getJustificationType().getOnlyHorizontalFlags())
|
||||||
|
.withLeading (lineSpacing);
|
||||||
|
|
||||||
if (wordWrap)
|
if (wordWrap)
|
||||||
options = options.withMaxWidth ((float) getMaximumTextWidth());
|
options = options.withMaxWidth ((float) getMaximumTextWidth());
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,7 @@ public:
|
||||||
The default (and minimum) value is 1.0 and values > 1.0 will increase the line spacing as a
|
The default (and minimum) value is 1.0 and values > 1.0 will increase the line spacing as a
|
||||||
multiple of the line height e.g. for double-spacing call this method with an argument of 2.0.
|
multiple of the line height e.g. for double-spacing call this method with an argument of 2.0.
|
||||||
*/
|
*/
|
||||||
void setLineSpacing (float newLineSpacing) noexcept { lineSpacing = jmax (1.0f, newLineSpacing); }
|
void setLineSpacing (float newLineSpacing) noexcept;
|
||||||
|
|
||||||
/** Returns the current line spacing of the TextEditor. */
|
/** Returns the current line spacing of the TextEditor. */
|
||||||
float getLineSpacing() const noexcept { return lineSpacing; }
|
float getLineSpacing() const noexcept { return lineSpacing; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue