mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Add ShapedText::accessTogetherWith and remove ShapedText::access
Since the original function template has been exposed, we can now use it directly. Also ShapedText::Detail has been removed, because it wouldn't work across module boundaries.
This commit is contained in:
parent
1b595311d0
commit
fab1de34ab
6 changed files with 77 additions and 114 deletions
|
|
@ -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 <typename Callable>
|
||||
void JustifiedText::access (Callable&& callback) const
|
||||
{
|
||||
accessTogetherWith (std::forward<Callable> (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<uint16_t> glyphIds (glyphs.size());
|
||||
std::vector<uint16_t> 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
|
||||
|
|
|
|||
|
|
@ -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<ValueType> arguments
|
||||
*/
|
||||
template <typename Callable, typename... RangedValues>
|
||||
void accessTogetherWith (Callable&& callback, RangedValues&&... rangedValues) const
|
||||
{
|
||||
|
|
@ -115,17 +133,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/* The callback receives (Span<const ShapedGlyph> glyphs,
|
||||
Span<Point<float>> positions,
|
||||
Font font,
|
||||
Range<int64> 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 <typename Callable>
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -44,11 +44,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void access (const std::function<void (Span<const ShapedGlyph>, Span<Point<float>>, Font, Range<int64>, 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<Impl> (std::move (text), std::move (options));
|
||||
}
|
||||
|
||||
void ShapedText::access (const std::function<void (Span<const ShapedGlyph>, Span<Point<float>>, Font, Range<int64>, int64)>& cb) const
|
||||
{
|
||||
impl->access (cb);
|
||||
}
|
||||
|
||||
void ShapedText::draw (const Graphics& g, AffineTransform transform) const
|
||||
{
|
||||
impl->draw (g, transform);
|
||||
|
|
@ -119,24 +109,8 @@ Span<const float> 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
|
||||
|
|
|
|||
|
|
@ -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<int64> 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<const float> getMinimumRequiredWidthForLines() const;
|
||||
|
||||
/** Provides access to the data stored in the ShapedText.
|
||||
/* @see JustifiedText::accessTogetherWith */
|
||||
template <typename Callable, typename... RangedValues>
|
||||
void accessTogetherWith (Callable&& callback, RangedValues&&... rangedValues) const
|
||||
{
|
||||
getJustifiedText().accessTogetherWith (std::forward<Callable> (callback),
|
||||
std::forward<RangedValues> (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<void (Span<const ShapedGlyph>, Span<Point<float>>, Font, Range<int64>, 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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -362,9 +362,9 @@ static Range<int64> 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<int64> 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<int64> lastLineNumber;
|
||||
std::unique_ptr<Line> line;
|
||||
|
||||
auto& jt = ShapedText::Detail { &shapedText }.getJustifiedText();
|
||||
jt.accessTogetherWith ([&] (Span<const ShapedGlyph> glyphs,
|
||||
st.accessTogetherWith ([&] (Span<const ShapedGlyph> glyphs,
|
||||
Span<Point<float>> positions,
|
||||
Font font,
|
||||
Range<int64> 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<Line> (castTo<int> (getLineInputRange (shapedText, lineNumber)),
|
||||
line = std::make_unique<Line> (castTo<int> (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<Run> (castTo<int> (getInputRange (shapedText, glyphRange)), 0);
|
||||
auto run = std::make_unique<Run> (castTo<int> (getInputRange (st, glyphRange)), 0);
|
||||
|
||||
run->font = font;
|
||||
run->colour = colour;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue