diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-15 12:51:21 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-15 12:51:21 +0300 | 
| commit | d9153532b8637cbfe992200effb1d24c597a732f (patch) | |
| tree | 123a168e400480ce9a8de780e068c232172c85cc /indra/llrender | |
| parent | b06a99f7c76950484972e25d9dbbee8660a6a6c3 (diff) | |
| parent | bb3c36f5cbc0c3b542045fd27255eee24e03da22 (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.cpp | 102 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 25 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.h | 4 | 
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(); | 
