summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-15 12:51:21 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-15 12:51:21 +0300
commitd9153532b8637cbfe992200effb1d24c597a732f (patch)
tree123a168e400480ce9a8de780e068c232172c85cc /indra/llrender
parentb06a99f7c76950484972e25d9dbbee8660a6a6c3 (diff)
parentbb3c36f5cbc0c3b542045fd27255eee24e03da22 (diff)
Merge branch 'main' into marchcat/x-mf-merge
# Conflicts: # doc/contributions.txt # indra/newview/llfloaterimagepreview.cpp
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontfreetype.cpp102
-rw-r--r--indra/llrender/llfontgl.cpp25
-rw-r--r--indra/llrender/llfontgl.h4
3 files changed, 99 insertions, 32 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 1e5e441689..92b373c835 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -354,11 +354,10 @@ void LLFontFreetype::clearFontStreams()
}
#endif
-void LLFontFreetype::addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font, const char_functor_t& functor)
+void LLFontFreetype::addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font,
+ const char_functor_t& functor)
{
- // Insert functor fallbacks before generic fallbacks
- mFallbackFonts.insert((functor) ? std::find_if(mFallbackFonts.begin(), mFallbackFonts.end(), [](const fallback_font_t& fe) { return !fe.second; }) : mFallbackFonts.end(),
- std::make_pair(fallback_font, functor));
+ mFallbackFonts.emplace_back(fallback_font, functor);
}
F32 LLFontFreetype::getLineHeight() const
@@ -450,50 +449,95 @@ BOOL LLFontFreetype::hasGlyph(llwchar wch) const
LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type) const
{
- if (mFTFace == NULL)
- return FALSE;
+ if (!mFTFace)
+ {
+ return NULL;
+ }
llassert(!mIsFallback);
llassert(glyph_type < EFontGlyphType::Count);
//LL_DEBUGS() << "Adding new glyph for " << wch << " to font" << LL_ENDL;
- FT_UInt glyph_index;
-
- // Fallback fonts with a functor have precedence over everything else
- fallback_font_vector_t::const_iterator it_fallback = mFallbackFonts.cbegin();
- /* This leads to a bug SL-19831 "Check marks in the menu are less visible."
- ** Also, LLFontRegistry::createFont() says: "Fallback fonts don't render"
- for (; it_fallback != mFallbackFonts.cend() && it_fallback->second; ++it_fallback)
+ // Initialize char to glyph map
+ FT_UInt glyph_index = FT_Get_Char_Index(mFTFace, wch);
+ if (glyph_index == 0)
{
- if (it_fallback->second(wch))
+ // No corresponding glyph in this font: look for a glyph in fallback
+ // fonts.
+ size_t count = mFallbackFonts.size();
+ if (LLStringOps::isEmoji(wch))
+ {
+ // This is a "genuine" emoji (in the range 0x1f000-0x20000): print
+ // it using the emoji font(s) if possible. HB
+ for (size_t i = 0; i < count; ++i)
+ {
+ const fallback_font_t& pair = mFallbackFonts[i];
+ if (!pair.second || !pair.second(wch))
+ {
+ // If this font does not have a functor, or the character
+ // does not pass the functor, reject it. Note: we keep the
+ // functor test (despite the fact we already tested for
+ // LLStringOps::isEmoji(wch) above), in case we would use
+ // different, more restrictive or partionned functors in
+ // the future with several different emoji fonts. HB
+ continue;
+ }
+ glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
+ if (glyph_index)
+ {
+ return addGlyphFromFont(pair.first, wch, glyph_index,
+ glyph_type);
+ }
+ }
+ }
+ // Then try and find a monochrome fallback font that could print this
+ // glyph: such fonts do *not* have a functor. We give priority to
+ // monochrome fonts for non-genuine emojis so that UI elements which
+ // used to render with them before the emojis font introduction (e.g.
+ // check marks in menus, or LSL dialogs text and buttons) do render the
+ // same way as they always did. HB
+ std::vector<size_t> emoji_fonts_idx;
+ for (size_t i = 0; i < count; ++i)
{
- glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
+ const fallback_font_t& pair = mFallbackFonts[i];
+ if (pair.second)
+ {
+ // If this font got a functor, remember the index for later and
+ // try the next fallback font. HB
+ emoji_fonts_idx.push_back(i);
+ continue;
+ }
+ glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
if (glyph_index)
{
- return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
+ return addGlyphFromFont(pair.first, wch, glyph_index,
+ glyph_type);
}
}
- }
- */
-
- // Initialize char to glyph map
- glyph_index = FT_Get_Char_Index(mFTFace, wch);
- if (glyph_index == 0)
- {
- //LL_INFOS() << "Trying to add glyph from fallback font!" << LL_ENDL;
- for (; it_fallback != mFallbackFonts.cend(); ++it_fallback)
+ // Everything failed so far: this character is not a genuine emoji,
+ // neither a special character known from our monochrome fallback
+ // fonts: make a last try, using the emoji font(s), but ignoring the
+ // functor to render using whatever (colorful) glyph that might be
+ // available in such fonts for this character. HB
+ for (size_t j = 0, count2 = emoji_fonts_idx.size(); j < count2; ++j)
{
- glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
+ const fallback_font_t& pair = mFallbackFonts[emoji_fonts_idx[j]];
+ glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
if (glyph_index)
{
- return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
+ return addGlyphFromFont(pair.first, wch, glyph_index,
+ glyph_type);
}
}
}
- std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
+ auto range_it = mCharGlyphInfoMap.equal_range(wch);
char_glyph_info_map_t::iterator iter =
- std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; });
+ std::find_if(range_it.first, range_it.second,
+ [&glyph_type](const char_glyph_info_map_t::value_type& entry)
+ {
+ return entry.second->mGlyphType == glyph_type;
+ });
if (iter == range_it.second)
{
return addGlyphFromFont(this, wch, glyph_index, glyph_type);
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 8d0fed7829..3714bb1883 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -276,6 +276,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
LLColor4U colors[GLYPH_BATCH_SIZE * 4];
LLColor4U text_color(color);
+ // Preserve the transparency to render fading emojis in fading text (e.g.
+ // for the chat console)... HB
+ LLColor4U emoji_color(255, 255, 255, text_color.mV[VW]);
std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
S32 glyph_count = 0;
@@ -344,7 +347,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
glyph_count = 0;
}
- drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, (bitmap_entry.first == EFontGlyphType::Grayscale) ? text_color : LLColor4U::white, style_to_add, shadow, drop_shadow_strength);
+ const LLColor4U& col =
+ bitmap_entry.first == EFontGlyphType::Grayscale ? text_color
+ : emoji_color;
+ drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect,
+ col, style_to_add, shadow, drop_shadow_strength);
chars_drawn++;
cur_x += fgi->mXAdvance;
@@ -1030,7 +1037,21 @@ LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
}
//static
-LLFontGL* LLFontGL::getFontEmoji()
+LLFontGL* LLFontGL::getFontEmojiSmall()
+{
+ static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Small", 0));
+ return fontp;;
+}
+
+//static
+LLFontGL* LLFontGL::getFontEmojiMedium()
+{
+ static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Medium", 0));
+ return fontp;;
+}
+
+//static
+LLFontGL* LLFontGL::getFontEmojiLarge()
{
static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Large", 0));
return fontp;;
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 2e1d04a2b9..65f0a8cbfd 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -194,7 +194,9 @@ public:
static void setFontDisplay(BOOL flag) { sDisplayFont = flag; }
- static LLFontGL* getFontEmoji();
+ static LLFontGL* getFontEmojiSmall();
+ static LLFontGL* getFontEmojiMedium();
+ static LLFontGL* getFontEmojiLarge();
static LLFontGL* getFontEmojiHuge();
static LLFontGL* getFontMonospace();
static LLFontGL* getFontSansSerifSmall();