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

Use detail::RangedValues<Font> on ShapedText related interfaces

Previously using the FontForRange type was motivated by hiding the
RangedValues type in case we wanted to expose the ShapedText API. This
introduced unnecessary conversions between FontForRange and
RangedValues<Font>.
This commit is contained in:
attila 2025-01-28 17:58:24 +01:00 committed by Attila Szarvas
parent ad43702e88
commit ef840b7472
3 changed files with 28 additions and 47 deletions

View file

@ -494,19 +494,19 @@ static auto makeSpan (T& array)
return Span { array.getRawDataPointer(), (size_t) array.size() };
}
static std::vector<FontForRange> findSuitableFontsForText (const Font& font,
const String& text,
const String& language = {})
static detail::RangedValues<Font> findSuitableFontsForText (const Font& font,
const String& text,
const String& language = {})
{
detail::RangedValues<std::optional<Font>> fonts;
fonts.set ({ 0, (int64) text.length() }, font);
const auto getResult = [&]
{
std::vector<FontForRange> result;
detail::RangedValues<Font> result;
for (const auto [r, v] : fonts)
result.emplace_back (r, v.value_or (font));
result.set (r, v.value_or (font));
return result;
};
@ -540,7 +540,7 @@ static std::vector<FontForRange> findSuitableFontsForText (const Font& font,
// can't find any more suitable fonts or all codepoints have one
for (auto numMissingGlyphs = markMissingGlyphs(); numMissingGlyphs > 0;)
{
std::vector<FontForRange> changes;
std::vector<std::pair<Range<int64>, Font>> changes;
for (const auto [r, f] : fonts)
{
@ -575,10 +575,8 @@ static RangedValues<Font> resolveFontsWithFallback (const String& string, const
auto rf = findSuitableFontsForText (f, string.substring ((int) r.getStart(),
(int) std::min (r.getEnd(), (int64) string.length())));
for (auto& item : rf)
item.first += r.getStart();
resolved.setForEach<MergeEqualItems::no> (rf.begin(), rf.end());
for (const auto [subRange, font] : rf)
resolved.set<MergeEqualItems::no> (subRange + r.getStart(), font);
}
return resolved;
@ -785,16 +783,11 @@ private:
};
template <typename T>
static auto createRangedValues (const std::vector<std::pair<Range<int64>, T>>& pairs, int64 offset = 0)
static auto rangedValuesWithOffset (detail::RangedValues<T> rv, int64 offset = 0)
{
detail::RangedValues<T> result;
for (const auto& [range, value] : pairs)
result.insert (range.movedToStartAt (range.getStart() - offset), value);
result.eraseUpTo (0);
return result;
rv.shift (std::numeric_limits<int64>::min(), -offset);
rv.eraseUpTo (0);
return rv;
}
struct Shaper
@ -819,8 +812,8 @@ struct Shaper
const auto bidiLevels = bidiParagraph.getResolvedLevels();
const auto fonts = resolveFontsWithFallback (string,
createRangedValues (options.getFontsForRange(),
shapingRange.getStart()));
rangedValuesWithOffset (options.getFontsForRange(),
shapingRange.getStart()));
for (Unicode::LineBreakIterator lineIter { makeSpan (analysis) }; auto lineRun = lineIter.next();)
{

View file

@ -35,8 +35,6 @@
namespace juce::detail
{
using FontForRange = std::pair<Range<int64>, Font>;
/** Types of text direction. This may also be applied to characters. */
enum class TextDirection
{
@ -64,12 +62,13 @@ public:
[[nodiscard]] ShapedTextOptions withFont (Font x) const
{
return withMember (*this, &ShapedTextOptions::fontsForRange,
std::vector<FontForRange> { { { 0, std::numeric_limits<int64>::max() },
x } });
RangedValues<Font> fonts;
fonts.set ({ 0, std::numeric_limits<int64>::max() }, x);
return withMember (*this, &ShapedTextOptions::fontsForRange, std::move (fonts));
}
[[nodiscard]] ShapedTextOptions withFontsForRange (const std::vector<FontForRange>& x) const
[[nodiscard]] ShapedTextOptions withFonts (const detail::RangedValues<Font>& x) const
{
return withMember (*this, &ShapedTextOptions::fontsForRange, x);
}
@ -151,8 +150,14 @@ private:
std::optional<TextDirection> readingDir;
std::optional<float> maxWidth;
std::optional<float> height;
std::vector<FontForRange> fontsForRange { { { 0, std::numeric_limits<int64>::max() },
FontOptions { 15.0f } } };
detail::RangedValues<Font> fontsForRange = std::invoke ([&]
{
detail::RangedValues<Font> result;
result.set ({ 0, std::numeric_limits<int64>::max() }, FontOptions { 15.0f });
return result;
});
String language = SystemStats::getDisplayLanguage();
float firstLineIndent = 0.0f;
float leading = 1.0f;

View file

@ -325,23 +325,6 @@ static auto castTo (const Range<U>& r)
return Range<T> (static_cast<T> (r.getStart()), static_cast<T> (r.getEnd()));
}
static auto getFontsForRange (const detail::RangedValues<Font>& fonts)
{
using namespace detail;
std::vector<FontForRange> result;
result.reserve (fonts.size());
std::transform (fonts.begin(),
fonts.end(),
std::back_inserter (result),
[] (auto entry) {
return FontForRange { entry.range, entry.value };
});
return result;
}
static Range<int64> getInputRange (const detail::ShapedText& st, Range<int64> glyphRange)
{
if (glyphRange.isEmpty())
@ -425,7 +408,7 @@ void TextLayout::createStandardLayout (const AttributedString& text)
colours.set (range, attribute.colour);
}
auto shapedTextOptions = ShapedTextOptions{}.withFontsForRange (getFontsForRange (fonts))
auto shapedTextOptions = ShapedTextOptions{}.withFonts (fonts)
.withLanguage (SystemStats::getUserLanguage())
.withTrailingWhitespacesShouldFit (false)
.withJustification (justification)