diff --git a/modules/juce_graphics/detail/juce_JustifiedText.cpp b/modules/juce_graphics/detail/juce_JustifiedText.cpp index daf1c7102e..a22adbf9d9 100644 --- a/modules/juce_graphics/detail/juce_JustifiedText.cpp +++ b/modules/juce_graphics/detail/juce_JustifiedText.cpp @@ -214,8 +214,8 @@ static float getCrossAxisStartingAnchor (Justification justification, return minimumTop; } -JustifiedText::JustifiedText (const SimpleShapedText& t, const ShapedTextOptions& options) - : shapedText (t) +JustifiedText::JustifiedText (const SimpleShapedText* t, const ShapedTextOptions& options) + : shapedText (*t) { const auto leading = options.getLeading() - 1.0f; @@ -443,32 +443,26 @@ JustifiedText::JustifiedText (const SimpleShapedText& t, const ShapedTextOptions realign.extraWhitespaceAdvance); } -template -void JustifiedText::access (Callable&& callback) const -{ - accessTogetherWith (std::forward (callback)); -} - void drawJustifiedText (const JustifiedText& text, const Graphics& g, AffineTransform transform) { auto& context = g.getInternalContext(); context.saveState(); const ScopeGuard restoreGraphicsContext { [&context] { context.restoreState(); } }; - text.access ([&] (auto glyphs, auto positions, auto font, auto, auto) - { - if (context.getFont() != font) - context.setFont (font); + text.accessTogetherWith ([&] (auto glyphs, auto positions, auto font, auto, auto) + { + if (context.getFont() != font) + context.setFont (font); - std::vector glyphIds (glyphs.size()); + std::vector glyphIds (glyphs.size()); - std::transform (glyphs.begin(), - glyphs.end(), - glyphIds.begin(), - [] (auto& glyph) { return (uint16_t) glyph.glyphId; }); + std::transform (glyphs.begin(), + glyphs.end(), + glyphIds.begin(), + [] (auto& glyph) { return (uint16_t) glyph.glyphId; }); - context.drawGlyphs (glyphIds, positions, transform); - }); + context.drawGlyphs (glyphIds, positions, transform); + }); } } // namespace juce::detail diff --git a/modules/juce_graphics/detail/juce_JustifiedText.h b/modules/juce_graphics/detail/juce_JustifiedText.h index 70a79ff7b2..073d277118 100644 --- a/modules/juce_graphics/detail/juce_JustifiedText.h +++ b/modules/juce_graphics/detail/juce_JustifiedText.h @@ -57,8 +57,26 @@ private: }; public: - JustifiedText (const SimpleShapedText& t, const ShapedTextOptions& options); + JustifiedText (const SimpleShapedText* t, const ShapedTextOptions& options); + /* Provides access to the data stored in the ShapedText. + + The provided callable will be called multiple times for "uniform glyph runs", for which all + callback parameters are the same. + + Between each subsequent callback at least one of the provided parameters will be different. + + The callbacks happen in visual order i.e. left to right, which is irrespective of the + underlying text's writing direction. + + The callback parameters in order are: + - the glyphs + - the positions for each glyph in the previous parameter + - the Font with which these glyphs should be rendered + - the range in all glyphs this ShapedText object holds, that correspond to the current glyphs + - a line number which increases by one for each new line + - followed by any number of ValueType parameters for the supplied RangedValues arguments + */ template void accessTogetherWith (Callable&& callback, RangedValues&&... rangedValues) const { @@ -115,17 +133,6 @@ public: } } - /* The callback receives (Span glyphs, - Span> positions, - Font font, - Range glyphRange, - int64 lineNumber) // So far this has been indexed from 0 per SimpleShapedText - // object, but maybe we'll find we want global text level - // line numbers, so only assume they are increasing by one - */ - template - void access (Callable&& callback) const; - /* This is how much cumulative widths glyphs take up in each line. Whether the trailing whitespace is included depends on the ShapedTextOptions::getWhitespaceShouldFitInLine() setting. diff --git a/modules/juce_graphics/detail/juce_ShapedText.cpp b/modules/juce_graphics/detail/juce_ShapedText.cpp index 69b4fc5e26..2e6edfa061 100644 --- a/modules/juce_graphics/detail/juce_ShapedText.cpp +++ b/modules/juce_graphics/detail/juce_ShapedText.cpp @@ -44,11 +44,6 @@ public: { } - void access (const std::function, Span>, Font, Range, int64)>& cb) const - { - justifiedText.access (cb); - } - void draw (const Graphics& g, AffineTransform transform) const { drawJustifiedText (justifiedText, g, transform); @@ -78,7 +73,7 @@ private: ShapedTextOptions options; String text; SimpleShapedText simpleShapedText { &text, options }; - JustifiedText justifiedText { simpleShapedText, options }; + JustifiedText justifiedText { &simpleShapedText, options }; }; ShapedText::ShapedText() : ShapedText ("", {}) @@ -94,11 +89,6 @@ ShapedText::ShapedText (String text, Options options) impl = std::make_shared (std::move (text), std::move (options)); } -void ShapedText::access (const std::function, Span>, Font, Range, int64)>& cb) const -{ - impl->access (cb); -} - void ShapedText::draw (const Graphics& g, AffineTransform transform) const { impl->draw (g, transform); @@ -119,24 +109,8 @@ Span ShapedText::getMinimumRequiredWidthForLines() const return impl->getMinimumRequiredWidthForLines(); } -class ShapedText::Detail -{ -public: - explicit Detail (const ShapedText* shapedTextIn) - : shapedText (*shapedTextIn) - {} +const JustifiedText& ShapedText::getJustifiedText() const { return impl->getJustifiedText(); } - auto& getJustifiedText() const { return shapedText.impl->getJustifiedText(); } - - auto& getSimpleShapedText() const { return shapedText.impl->getSimpleShapedText(); } - -private: - const ShapedText& shapedText; -}; - -ShapedText::Detail ShapedText::getDetail() const -{ - return Detail { this }; -} +const SimpleShapedText& ShapedText::getSimpleShapedText() const { return impl->getSimpleShapedText(); } } // namespace juce::detail diff --git a/modules/juce_graphics/detail/juce_ShapedText.h b/modules/juce_graphics/detail/juce_ShapedText.h index 1ae07de763..3b9a3e72e6 100644 --- a/modules/juce_graphics/detail/juce_ShapedText.h +++ b/modules/juce_graphics/detail/juce_ShapedText.h @@ -35,7 +35,7 @@ namespace juce::detail { -/** Class that can visually shape a Unicode string provided a list of Fonts corresponding to +/* Class that can visually shape a Unicode string provided a list of Fonts corresponding to sub-ranges of the string. */ class JUCE_API ShapedText @@ -49,17 +49,17 @@ public: ShapedText (String text, Options options); - /** Returns the text which was used to construct this object. */ + /* Returns the text which was used to construct this object. */ const String& getText() const; - /** Returns the text's codepoint range, to which the glyph under the provided index belongs. + /* Returns the text's codepoint range, to which the glyph under the provided index belongs. This range will have a length of at least one, and potentially more than one if ligatures are enabled. */ Range getTextRange (int64 glyphIndex) const; - /** Returns the widths for each line, that the glyphs would require to be rendered without being + /* Returns the widths for each line, that the glyphs would require to be rendered without being truncated. This will or will not include the space required by trailing whitespaces in the line based on the ShapedTextOptions::withTrailingWhitespacesShouldFit() value. @@ -68,33 +68,22 @@ public: */ Span getMinimumRequiredWidthForLines() const; - /** Provides access to the data stored in the ShapedText. + /* @see JustifiedText::accessTogetherWith */ + template + void accessTogetherWith (Callable&& callback, RangedValues&&... rangedValues) const + { + getJustifiedText().accessTogetherWith (std::forward (callback), + std::forward (rangedValues)...); + } - The provided function callback will be called multiple times for "uniform glyph runs", for which all - callback parameters are the same. - - Between each subsequent callback at least one of the provided parameters will be different. - - The callbacks happen in visual order i.e. left to right, which is irrespective of the - underlying text's writing direction. - - The callback parameters in order are: - - the glyphs - - the positions for each glyph in the previous parameter - - the Font with which these glyphs should be rendered - - the range in all glyphs this ShapedText object holds, that correspond to the current glyphs - - a line number which increases by one for each new line - */ - void access (const std::function, Span>, Font, Range, int64)>&) const; - - /** Draws the text. */ + /* Draws the text. */ void draw (const Graphics& g, AffineTransform transform) const; - /** @internal */ - class Detail; + /* @internal */ + const JustifiedText& getJustifiedText() const; - /** @internal */ - Detail getDetail() const; + /* @internal */ + const SimpleShapedText& getSimpleShapedText() const; private: class Impl; diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp index 0060393c3c..b4376d919d 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp @@ -173,26 +173,26 @@ void GlyphArrangement::addLineOfText (const Font& font, const String& text, floa static void addGlyphsFromShapedText (GlyphArrangement& ga, const detail::ShapedText& st, float x, float y) { - st.access ([&] (auto shapedGlyphs, auto positions, auto font, auto glyphRange, auto) - { - for (size_t i = 0; i < shapedGlyphs.size(); ++i) - { - const auto glyphIndex = (int64) i + glyphRange.getStart(); + st.accessTogetherWith ([&] (auto shapedGlyphs, auto positions, auto font, auto glyphRange, auto) + { + for (size_t i = 0; i < shapedGlyphs.size(); ++i) + { + const auto glyphIndex = (int64) i + glyphRange.getStart(); - auto& glyph = shapedGlyphs[i]; - auto& position = positions[i]; + auto& glyph = shapedGlyphs[i]; + auto& position = positions[i]; - PositionedGlyph pg { font, - st.getText()[(int) st.getTextRange (glyphIndex).getStart()], - (int) glyph.glyphId, - position.getX() + x, - position.getY() + y, - glyph.advance.getX(), - glyph.whitespace }; + PositionedGlyph pg { font, + st.getText()[(int) st.getTextRange (glyphIndex).getStart()], + (int) glyph.glyphId, + position.getX() + x, + position.getY() + y, + glyph.advance.getX(), + glyph.whitespace }; - ga.addGlyph (std::move (pg)); - } - }); + ga.addGlyph (std::move (pg)); + } + }); } void GlyphArrangement::addCurtailedLineOfText (const Font& font, const String& text, diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index 16a8fdcac8..2c6dd56422 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -362,9 +362,9 @@ static Range getLineInputRange (const detail::ShapedText& st, int64 lineN { using namespace detail; - return getInputRange (st, ShapedText::Detail { &st }.getSimpleShapedText() - .getLineNumbers() - .getItem ((size_t) lineNumber).range); + return getInputRange (st, st.getSimpleShapedText() + .getLineNumbers() + .getItem ((size_t) lineNumber).range); } struct MaxFontAscentAndDescent @@ -375,7 +375,7 @@ struct MaxFontAscentAndDescent static MaxFontAscentAndDescent getMaxFontAscentAndDescentInEnclosingLine (const detail::ShapedText& st, Range lineChunkRange) { - const auto sst = detail::ShapedText::Detail { &st }.getSimpleShapedText(); + const auto sst = st.getSimpleShapedText(); const auto lineRange = sst.getLineNumbers() .getItemWithEnclosingRange (lineChunkRange.getStart())->range; @@ -435,13 +435,12 @@ void TextLayout::createStandardLayout (const AttributedString& text) if (text.getWordWrap() != AttributedString::none) shapedTextOptions = shapedTextOptions.withMaxWidth (width); - ShapedText shapedText { text.getText(), shapedTextOptions }; + ShapedText st { text.getText(), shapedTextOptions }; std::optional lastLineNumber; std::unique_ptr line; - auto& jt = ShapedText::Detail { &shapedText }.getJustifiedText(); - jt.accessTogetherWith ([&] (Span glyphs, + st.accessTogetherWith ([&] (Span glyphs, Span> positions, Font font, Range glyphRange, @@ -453,10 +452,10 @@ void TextLayout::createStandardLayout (const AttributedString& text) if (line != nullptr) addLine (std::move (line)); - const auto ascentAndDescent = getMaxFontAscentAndDescentInEnclosingLine (shapedText, + const auto ascentAndDescent = getMaxFontAscentAndDescentInEnclosingLine (st, glyphRange); - line = std::make_unique (castTo (getLineInputRange (shapedText, lineNumber)), + line = std::make_unique (castTo (getLineInputRange (st, lineNumber)), positions[0], ascentAndDescent.ascent, ascentAndDescent.descent, @@ -464,7 +463,7 @@ void TextLayout::createStandardLayout (const AttributedString& text) 0); } - auto run = std::make_unique (castTo (getInputRange (shapedText, glyphRange)), 0); + auto run = std::make_unique (castTo (getInputRange (st, glyphRange)), 0); run->font = font; run->colour = colour;