From 5a6ddb2ea666e895890d3cb690cce5101cf12652 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 7 Nov 2019 17:15:21 +0100 Subject: Fallback fonts can have first crack at adding an unknown character + set Twemoji as the viewer's fallback for all emoji blocks --- indra/llcommon/llstring.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'indra/llcommon/llstring.cpp') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 0174c411b4..b272728200 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -30,6 +30,7 @@ #include "llerror.h" #include "llfasttimer.h" #include "llsd.h" +#include #include #if LL_WINDOWS @@ -888,6 +889,31 @@ std::string LLStringOps::sDayFormat; std::string LLStringOps::sAM; std::string LLStringOps::sPM; +// static +bool LLStringOps::isEmoji(llwchar wch) +{ + switch (ublock_getCode(wch)) + { + case UBLOCK_MISCELLANEOUS_SYMBOLS: + case UBLOCK_DINGBATS: + case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS: + case UBLOCK_EMOTICONS: + case UBLOCK_TRANSPORT_AND_MAP_SYMBOLS: +#if U_ICU_VERSION_MAJOR_NUM > 56 + // Boost uses ICU so we can't update it independently + case UBLOCK_SUPPLEMENTAL_SYMBOLS_AND_PICTOGRAPHS: +#endif // U_ICU_VERSION_MAJOR_NUM > 56 + return true; + default: +#if U_ICU_VERSION_MAJOR_NUM > 56 + return false; +#else + // See https://en.wikipedia.org/wiki/Supplemental_Symbols_and_Pictographs + return wch >= 0x1F900 && wch <= 0x1F9FF; +#endif // U_ICU_VERSION_MAJOR_NUM > 56 + } +} + S32 LLStringOps::collate(const llwchar* a, const llwchar* b) { -- cgit v1.3 From 671978e3927bc3ba9fc34008bbb7efd6f07b6c81 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Wed, 17 May 2023 14:28:36 +0200 Subject: SL-19575 Create emoji gallery (fix bug with drawing emojis in chat history) --- indra/llcommon/llstring.cpp | 13 ++++- indra/llui/llemojidictionary.cpp | 11 ++++ indra/llui/llemojidictionary.h | 1 + indra/llui/lltextbase.cpp | 41 ++++++++------ indra/llui/lltextbase.h | 2 +- indra/newview/llchathistory.cpp | 62 +++++++--------------- indra/newview/llfloateremojipicker.cpp | 38 +++++++++---- indra/newview/llfloateremojipicker.h | 2 +- indra/newview/llfloaterimsessiontab.cpp | 50 ++++++++--------- indra/newview/llfloaterimsessiontab.h | 2 +- indra/newview/llscripteditor.cpp | 2 +- .../skins/default/xui/en/widgets/chat_history.xml | 10 ++-- 12 files changed, 125 insertions(+), 109 deletions(-) (limited to 'indra/llcommon/llstring.cpp') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index cda1791e45..d68cbaa22c 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -837,10 +837,19 @@ std::string LLStringOps::sPM; // static bool LLStringOps::isEmoji(llwchar wch) { - switch (ublock_getCode(wch)) - { + int ublock = ublock_getCode(wch); + switch (ublock) + { + case UBLOCK_GENERAL_PUNCTUATION: + case UBLOCK_LETTERLIKE_SYMBOLS: + case UBLOCK_ARROWS: + case UBLOCK_MISCELLANEOUS_TECHNICAL: + case UBLOCK_ENCLOSED_ALPHANUMERICS: + case UBLOCK_GEOMETRIC_SHAPES: case UBLOCK_MISCELLANEOUS_SYMBOLS: case UBLOCK_DINGBATS: + case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION: + case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS: case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS: case UBLOCK_EMOTICONS: case UBLOCK_TRANSPORT_AND_MAP_SYMBOLS: diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp index bb5c94689a..179c5d25bf 100644 --- a/indra/llui/llemojidictionary.cpp +++ b/indra/llui/llemojidictionary.cpp @@ -199,6 +199,17 @@ std::string LLEmojiDictionary::getNameFromEmoji(llwchar ch) const return (mEmoji2Descr.end() != it) ? it->second->Name : LLStringUtil::null; } +bool LLEmojiDictionary::isEmoji(llwchar ch) const +{ + // Currently used codes: A9,AE,203C,2049,2122,...,2B55,3030,303D,3297,3299,1F004,...,1FAF6 + if (ch == 0xA9 || ch == 0xAE || (ch >= 0x2000 && ch < 0x3300) || (ch >= 0x1F000 && ch < 0x20000)) + { + return mEmoji2Descr.find(ch) != mEmoji2Descr.end(); + } + + return false; +} + void LLEmojiDictionary::addEmoji(LLEmojiDescriptor&& descr) { mEmojis.push_back(descr); diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h index 88ff5b8300..cc26f75ea3 100644 --- a/indra/llui/llemojidictionary.h +++ b/indra/llui/llemojidictionary.h @@ -68,6 +68,7 @@ public: const LLEmojiDescriptor* getDescriptorFromEmoji(llwchar emoji) const; const LLEmojiDescriptor* getDescriptorFromShortCode(const std::string& short_code) const; std::string getNameFromEmoji(llwchar ch) const; + bool isEmoji(llwchar ch) const; const emoji2descr_map_t& getEmoji2Descr() const { return mEmoji2Descr; } const code2descr_map_t& getShortCode2Descr() const { return mShortCode2Descr; } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0066e09cfc..e7273c96c1 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -29,6 +29,7 @@ #include "lltextbase.h" +#include "llemojidictionary.h" #include "llemojihelper.h" #include "lllocalcliprect.h" #include "llmenugl.h" @@ -366,7 +367,7 @@ void LLTextBase::onValueChange(S32 start, S32 end) { } -std::vector LLTextBase::getSelctionRects() +std::vector LLTextBase::getSelectionRects() { // Nor supposed to be called without selection llassert(hasSelection()); @@ -463,7 +464,7 @@ void LLTextBase::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if (hasSelection() && !mLineInfoList.empty()) { - std::vector selection_rects = getSelctionRects(); + std::vector selection_rects = getSelectionRects(); // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -904,9 +905,12 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s // Insert special segments where necessary (insertSegment takes care of splitting normal text segments around them for us) { LLStyleSP emoji_style; + LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL; for (S32 text_kitty = 0, text_len = wstr.size(); text_kitty < text_len; text_kitty++) { - if (LLStringOps::isEmoji(wstr[text_kitty])) + llwchar code = wstr[text_kitty]; + bool isEmoji = ed ? ed->isEmoji(code) : LLStringOps::isEmoji(code); + if (isEmoji) { if (!emoji_style) { @@ -2181,8 +2185,8 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para S32 start=0,end=0; LLUrlMatch match; std::string text = new_text; - while ( LLUrlRegistry::instance().findUrl(text, match, - boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted() || mAlwaysShowIcons)) + while (LLUrlRegistry::instance().findUrl(text, match, + boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3), isContentTrusted() || mAlwaysShowIcons)) { start = match.getStart(); end = match.getEnd()+1; @@ -2430,18 +2434,18 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig LLStyle::Params normal_style_params(style_params); normal_style_params.font.style("NORMAL"); LLStyleConstSP normal_sp(new LLStyle(normal_style_params)); - segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this )); + segments.push_back(new LLOnHoverChangeableTextSegment(sp, normal_sp, segment_start, segment_end, *this)); } else { - segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this )); + segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this)); } insertStringNoUndo(getLength(), wide_text, &segments); } // Set the cursor and scroll position - if( selection_start != selection_end ) + if (selection_start != selection_end) { mSelectionStart = selection_start; mSelectionEnd = selection_end; @@ -2449,7 +2453,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig mIsSelecting = was_selecting; setCursorPos(cursor_pos); } - else if( cursor_was_at_end ) + else if (cursor_was_at_end) { setCursorPos(getLength()); } @@ -2461,25 +2465,28 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) { - if (new_text.empty()) return; + if (new_text.empty()) + { + return; + } std::string::size_type start = 0; - std::string::size_type pos = new_text.find("\n",start); + std::string::size_type pos = new_text.find("\n", start); - while(pos!=-1) + while (pos != std::string::npos) { - if(pos!=start) + if (pos != start) { std::string str = std::string(new_text,start,pos-start); - appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only); + appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only); } appendLineBreakSegment(style_params); start = pos+1; - pos = new_text.find("\n",start); + pos = new_text.find("\n", start); } - std::string str = std::string(new_text,start,new_text.length()-start); - appendAndHighlightTextImpl(str,highlight_part, style_params, underline_on_hover_only); + std::string str = std::string(new_text, start, new_text.length() - start); + appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 9b3691e404..37ab798a1d 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -654,7 +654,7 @@ protected: return mLabel.getString() + getToolTip(); } - std::vector getSelctionRects(); + std::vector getSelectionRects(); protected: // text segmentation and flow diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index f4fa449ca2..f29d7ec29b 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -1215,9 +1215,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL llassert(mEditor); if (!mEditor) - { return; - } bool from_me = chat.mFromID == gAgent.getID(); mEditor->setPlainText(use_plain_text_chat_history); @@ -1227,26 +1225,16 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mUnreadChatSources.insert(chat.mFromName); mMoreChatPanel->setVisible(TRUE); std::string chatters; - for (unread_chat_source_t::iterator it = mUnreadChatSources.begin(); - it != mUnreadChatSources.end();) + for (const std::string& source : mUnreadChatSources) { - chatters += *it; - if (++it != mUnreadChatSources.end()) - { - chatters += ", "; - } + chatters += chatters.size() ? ", " + source : source; } LLStringUtil::format_map_t args; args["SOURCES"] = chatters; - if (mUnreadChatSources.size() == 1) - { - mMoreChatText->setValue(LLTrans::getString("unread_chat_single", args)); - } - else - { - mMoreChatText->setValue(LLTrans::getString("unread_chat_multiple", args)); - } + std::string xml_desc = mUnreadChatSources.size() == 1 ? + "unread_chat_single" : "unread_chat_multiple"; + mMoreChatText->setValue(LLTrans::getString(xml_desc, args)); S32 height = mMoreChatText->getTextPixelHeight() + 5; mMoreChatPanel->reshape(mMoreChatPanel->getRect().getWidth(), height); } @@ -1294,11 +1282,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL body_message_params.font.style = "ITALIC"; } - if(chat.mChatType == CHAT_TYPE_WHISPER) + if (chat.mChatType == CHAT_TYPE_WHISPER) { body_message_params.font.style = "ITALIC"; } - else if(chat.mChatType == CHAT_TYPE_SHOUT) + else if (chat.mChatType == CHAT_TYPE_SHOUT) { body_message_params.font.style = "BOLD"; } @@ -1345,10 +1333,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } // names showing - if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0) + if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size()) { // Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text. - if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) + if (chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull()) { // for object IMs, create a secondlife:///app/objectim SLapp std::string url = LLViewerChat::getSenderSLURL(chat, args); @@ -1408,36 +1396,27 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL && mIsLastMessageFromLog == message_from_log) //distinguish between current and previous chat session's histories { view = getSeparator(); - p.top_pad = mTopSeparatorPad; - p.bottom_pad = mBottomSeparatorPad; if (!view) { // Might be wiser to make this LL_ERRS, getSeparator() should work in case of correct instalation. LL_WARNS() << "Failed to create separator from " << mMessageSeparatorFilename << ": can't append to history" << LL_ENDL; return; } + + p.top_pad = mTopSeparatorPad; + p.bottom_pad = mBottomSeparatorPad; } else { view = getHeader(chat, name_params, args); - if (mEditor->getLength() == 0) - p.top_pad = 0; - else - p.top_pad = mTopHeaderPad; - if (teleport_separator) - { - p.bottom_pad = mBottomSeparatorPad; - } - else - { - p.bottom_pad = mBottomHeaderPad; - } - if (!view) - { - LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL; - return; - } + if (!view) + { + LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL; + return; + } + p.top_pad = mEditor->getLength() ? mTopHeaderPad : 0; + p.bottom_pad = teleport_separator ? mBottomSeparatorPad : mBottomHeaderPad; } p.view = view; @@ -1510,11 +1489,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL } } // usual messages showing - else if(!teleport_separator) + else if (!teleport_separator) { std::string message = irc_me ? chat.mText.substr(3) : chat.mText; - //MESSAGE TEXT PROCESSING //*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010) if (use_plain_text_chat_history && !from_me && chat.mFromID.notNull()) diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index 9d28f7d4dc..98fe1e7ca1 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -60,9 +60,25 @@ public: { LLScrollListItem::draw(rect, fg_color, hover_color, select_color, highlight_color, column_padding); + LLWString wstr(1, mEmoji); S32 width = getColumn(0)->getWidth(); - LLFontGL::getFontEmoji()->render(LLWString(1, mEmoji), 0, rect.mLeft + width / 2, rect.getCenterY(), LLColor4::white, - LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW_SOFT, 1, S32_MAX, nullptr, false, true); + F32 x = rect.mLeft + width / 2; + F32 y = rect.getCenterY(); + LLFontGL::getFontEmoji()->render( + wstr, // wstr + 0, // begin_offset + x, // x + y, // y + LLColor4::white, // color + LLFontGL::HCENTER, // halign + LLFontGL::VCENTER, // valign + LLFontGL::NORMAL, // style + LLFontGL::DROP_SHADOW_SOFT, // shadow + 1, // max_chars + S32_MAX, // max_pixels + nullptr, // right_x + false, // use_ellipses + true); // use_color } private: @@ -101,13 +117,13 @@ BOOL LLFloaterEmojiPicker::postBuild() { // Should be initialized first mPreviewEmoji = getChild("PreviewEmoji"); - mPreviewEmoji->setClickedCallback(boost::bind(&LLFloaterEmojiPicker::onPreviewEmojiClick, this)); + mPreviewEmoji->setClickedCallback([this](LLUICtrl*, const LLSD&) { onPreviewEmojiClick(); }); mCategory = getChild("Category"); - mCategory->setCommitCallback(boost::bind(&LLFloaterEmojiPicker::onCategoryCommit, this)); + mCategory->setCommitCallback([this](LLUICtrl*, const LLSD&) { onCategoryCommit(); }); const LLEmojiDictionary::cat2descrs_map_t& cat2Descrs = LLEmojiDictionary::instance().getCategory2Descrs(); mCategory->clearRows(); - for (const LLEmojiDictionary::cat2descrs_item_t& item : cat2Descrs) + for (const LLEmojiDictionary::cat2descrs_item_t item : cat2Descrs) { std::string value = item.first; std::string name = value; @@ -117,13 +133,13 @@ BOOL LLFloaterEmojiPicker::postBuild() mCategory->setSelectedByValue(mSelectedCategory, true); mSearch = getChild("Search"); - mSearch->setKeystrokeCallback(boost::bind(&LLFloaterEmojiPicker::onSearchKeystroke, this, _1, _2), NULL); + mSearch->setKeystrokeCallback([this](LLLineEditor*, void*) { onSearchKeystroke(); }, NULL); mSearch->setFont(LLViewerChat::getChatFont()); mSearch->setText(mSearchPattern); mEmojis = getChild("Emojis"); - mEmojis->setCommitCallback(boost::bind(&LLFloaterEmojiPicker::onEmojiSelect, this)); - mEmojis->setDoubleClickCallback(boost::bind(&LLFloaterEmojiPicker::onEmojiPick, this)); + mEmojis->setCommitCallback([this](LLUICtrl*, const LLSD&) { onEmojiSelect(); }); + mEmojis->setDoubleClickCallback([this]() { onEmojiPick(); }); fillEmojis(); return TRUE; @@ -139,7 +155,7 @@ void LLFloaterEmojiPicker::fillEmojis() mEmojis->clearRows(); const LLEmojiDictionary::emoji2descr_map_t& emoji2Descr = LLEmojiDictionary::instance().getEmoji2Descr(); - for (const LLEmojiDictionary::emoji2descr_item_t& it : emoji2Descr) + for (const LLEmojiDictionary::emoji2descr_item_t it : emoji2Descr) { const LLEmojiDescriptor* descr = it.second; @@ -150,6 +166,8 @@ void LLFloaterEmojiPicker::fillEmojis() continue; LLScrollListItem::Params params; + // The following line adds default monochrome view of the emoji (is shown as an example) + //params.columns.add().column("look").value(wstring_to_utf8str(LLWString(1, it.first))); params.columns.add().column("name").value(descr->Name); mEmojis->addRow(new LLEmojiScrollListItem(it.first, params), params); } @@ -194,7 +212,7 @@ void LLFloaterEmojiPicker::onCategoryCommit() fillEmojis(); } -void LLFloaterEmojiPicker::onSearchKeystroke(LLLineEditor* caller, void* user_data) +void LLFloaterEmojiPicker::onSearchKeystroke() { mSearchPattern = mSearch->getText(); mSelectedEmojiIndex = 0; diff --git a/indra/newview/llfloateremojipicker.h b/indra/newview/llfloateremojipicker.h index 01335bbb5b..7327fb945e 100644 --- a/indra/newview/llfloateremojipicker.h +++ b/indra/newview/llfloateremojipicker.h @@ -57,7 +57,7 @@ private: bool matchesPattern(const LLEmojiDescriptor* descr); void onCategoryCommit(); - void onSearchKeystroke(class LLLineEditor* caller, void* user_data); + void onSearchKeystroke(); void onPreviewEmojiClick(); void onEmojiSelect(); void onEmojiEmpty(); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 0571a0d855..dbd2d71f94 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -435,8 +435,8 @@ void LLFloaterIMSessionTab::onEmojiPanelBtnClicked(LLFloaterIMSessionTab* self) if (!picker->isShown()) { picker->show( - boost::bind(&LLFloaterIMSessionTab::onEmojiPicked, self, _1), - boost::bind(&LLFloaterIMSessionTab::onEmojiPickerClosed, self)); + [self](llwchar emoji) { self->onEmojiPicked(emoji); }, + [self]() { self->onEmojiPickerClosed(); }); if (LLFloater* root_floater = gFloaterView->getParentFloater(self)) { root_floater->addDependentFloater(picker, TRUE, TRUE); @@ -461,51 +461,43 @@ void LLFloaterIMSessionTab::onEmojiPickerClosed() std::string LLFloaterIMSessionTab::appendTime() { - time_t utc_time; - utc_time = time_corrected(); - std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"]"; + std::string timeStr = "[" + LLTrans::getString("TimeHour") + "]:" + "[" + LLTrans::getString("TimeMin") + "]"; LLSD substitution; - - substitution["datetime"] = (S32) utc_time; - LLStringUtil::format (timeStr, substitution); + substitution["datetime"] = (S32)time_corrected(); + LLStringUtil::format(timeStr, substitution); return timeStr; } -void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) +void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD& args) { + if (chat.mMuted || !mChatHistory) + return; // Update the participant activity time LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance(); if (im_box) { - im_box->setTimeNow(mSessionID,chat.mFromID); + im_box->setTimeNow(mSessionID, chat.mFromID); } - LLChat& tmp_chat = const_cast(chat); - if(tmp_chat.mTimeStr.empty()) + if (tmp_chat.mTimeStr.empty()) tmp_chat.mTimeStr = appendTime(); - if (!chat.mMuted) - { - tmp_chat.mFromName = chat.mFromName; - LLSD chat_args; - if (args) chat_args = args; - chat_args["use_plain_text_chat_history"] = - gSavedSettings.getBOOL("PlainTextChatHistory"); - chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); - chat_args["show_names_for_p2p_conv"] = - !mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); - - if (mChatHistory) - { - mChatHistory->appendMessage(chat, chat_args); - } - } + tmp_chat.mFromName = chat.mFromName; + + LLSD chat_args = args; + chat_args["use_plain_text_chat_history"] = + gSavedSettings.getBOOL("PlainTextChatHistory"); + chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime"); + chat_args["show_names_for_p2p_conv"] = !mIsP2PChat || + gSavedSettings.getBOOL("IMShowNamesForP2PConv"); + + mChatHistory->appendMessage(chat, chat_args); } static LLTrace::BlockTimerStatHandle FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT("Build Conversation View"); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 3dcb767aa6..49be4f6bd1 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -140,7 +140,7 @@ protected: /* virtual */ void onFocusReceived(); // prepare chat's params and out one message to chatHistory - void appendMessage(const LLChat& chat, const LLSD &args = 0); + void appendMessage(const LLChat& chat, const LLSD& args = LLSD()); std::string appendTime(); void assignResizeLimits(); diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 140cbbedbe..3278bd3aa9 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -187,7 +187,7 @@ void LLScriptEditor::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if( hasSelection() && !mLineInfoList.empty()) { - std::vector selection_rects = getSelctionRects(); + std::vector selection_rects = getSelectionRects(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor; diff --git a/indra/newview/skins/default/xui/en/widgets/chat_history.xml b/indra/newview/skins/default/xui/en/widgets/chat_history.xml index c0a948931c..c4300c9350 100644 --- a/indra/newview/skins/default/xui/en/widgets/chat_history.xml +++ b/indra/newview/skins/default/xui/en/widgets/chat_history.xml @@ -10,11 +10,11 @@ bottom_separator_pad="1" top_header_pad="12" bottom_header_pad="5" - max_length="2147483647" - track_bottom="true" - name="chat_history" - type="string" - word_wrap="true" + max_length="2147483647" + track_bottom="true" + name="chat_history" + type="string" + word_wrap="true" line_spacing.multiple="1.0" font="SansSerif"> Date: Thu, 30 Nov 2023 13:59:14 +0100 Subject: SL-19801 Log unicode characters for debug --- indra/llcommon/llstring.cpp | 24 ++++++++++++++++++++++++ indra/llcommon/llstring.h | 2 ++ indra/llui/lltexteditor.cpp | 1 + indra/llui/llview.cpp | 2 +- 4 files changed, 28 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/llstring.cpp') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index d68cbaa22c..81b0207038 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -365,6 +365,30 @@ S32 wchar_utf8_length(const llwchar wc) } } +std::string wchar_utf8_preview(const llwchar wc) +{ + std::ostringstream oss; + oss << std::hex << std::uppercase << (U32)wc; + + U8 out_bytes[8]; + U32 size = (U32)wchar_to_utf8chars(wc, (char*)out_bytes); + + if (size > 1) + { + oss << " ["; + for (U32 i = 0; i < size; ++i) + { + if (i) + { + oss << ", "; + } + oss << (int)out_bytes[i]; + } + oss << "]"; + } + + return oss.str(); +} S32 wstring_utf8_length(const LLWString& wstr) { diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 62403969e4..8def59ed7f 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -682,6 +682,8 @@ LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); // Length in bytes of this wide char in a UTF8 string LL_COMMON_API S32 wchar_utf8_length(const llwchar wc); +LL_COMMON_API std::string wchar_utf8_preview(const llwchar wc); + LL_COMMON_API std::string utf8str_tolower(const std::string& utf8str); // Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string. diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 7aef056e5a..3910be1443 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -682,6 +682,7 @@ void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_p void LLTextEditor::insertEmoji(llwchar emoji) { + LL_INFOS() << "LLTextEditor::insertEmoji(" << wchar_utf8_preview(emoji) << ")" << LL_ENDL; auto styleParams = LLStyle::Params(); styleParams.font = LLFontGL::getFontEmoji(); auto segment = new LLEmojiTextSegment(new LLStyle(styleParams), mCursorPos, mCursorPos + 1, *this); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 0046105870..7b6661a519 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1024,7 +1024,7 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) handled = handleUnicodeCharHere(uni_char); if (handled && LLView::sDebugKeys) { - LL_INFOS() << "Unicode key handled by " << getName() << LL_ENDL; + LL_INFOS() << "Unicode key " << wchar_utf8_preview(uni_char) << " is handled by " << getName() << LL_ENDL; } } } -- cgit v1.3 From ae91ae43a51c58cc496f3947921fbf886c6be86e Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 15 Jan 2024 23:20:24 +0100 Subject: SL-20795 Part of previously typed emojis disappear in the 'Save settings as a preset...' option of the 'Preferences' floater --- indra/llcommon/llstring.cpp | 2 -- indra/llrender/llfontfreetype.cpp | 11 ++++++++++- indra/llrender/llfontgl.cpp | 6 +++--- indra/llrender/llfontgl.h | 8 ++++---- indra/llui/llbutton.cpp | 2 +- indra/llui/llfolderviewitem.cpp | 10 +++++----- indra/llui/lllineeditor.cpp | 2 +- indra/llui/llview.cpp | 3 +-- indra/newview/llfloateremojipicker.cpp | 22 ++++------------------ indra/newview/llfloateruipreview.cpp | 8 ++++---- indra/newview/llpanelemojicomplete.cpp | 8 ++++---- indra/newview/lltextureview.cpp | 3 +-- indra/newview/llviewerwindow.cpp | 3 +-- indra/newview/llworldmapview.cpp | 3 +-- .../default/xui/en/panel_preferences_graphics1.xml | 2 +- 15 files changed, 41 insertions(+), 52 deletions(-) (limited to 'indra/llcommon/llstring.cpp') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 81b0207038..17d69351ec 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -339,8 +339,6 @@ S32 wchar_utf8_length(const llwchar wc) { if (wc < 0x80) { - // This case will also catch negative values which are - // technically invalid. return 1; } else if (wc < 0x800) diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index ca9f2ed778..d87fb5245c 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -665,7 +665,16 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co load_flags |= FT_LOAD_COLOR; } - llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, load_flags) ); + FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags); + if (FT_Err_Ok != error) + { + std::string message = llformat( + "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d", + error, FT_Error_String(error), glyph_index, bitmap_type, load_flags); + LL_WARNS_ONCE() << message << LL_ENDL; + error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); + llassert_always_msg(FT_Err_Ok == error, message.c_str()); + } llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) ); diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index f0b89f9a1d..53661b6a63 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -420,7 +420,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const { - return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE); + return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW); } S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const @@ -430,12 +430,12 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE); + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW); } S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE, FALSE); + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow); } // font metrics - override for LLFontFreetype that returns units of virtual pixels diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index a9d512f7ce..f6ec416c8b 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -99,7 +99,7 @@ public: S32 max_chars = S32_MAX, F32* right_x=NULL, BOOL use_ellipses = FALSE, - BOOL use_color = FALSE) const; + BOOL use_color = TRUE) const; S32 render(const LLWString &text, S32 begin_offset, const LLRectf& rect, @@ -109,7 +109,7 @@ public: S32 max_chars = S32_MAX, F32* right_x=NULL, BOOL use_ellipses = FALSE, - BOOL use_color = FALSE) const; + BOOL use_color = TRUE) const; S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, @@ -119,12 +119,12 @@ public: S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_ellipses = FALSE, - BOOL use_color = FALSE) const; + BOOL use_color = TRUE) const; S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const; // renderUTF8 does a conversion, so is slower! - S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const; + S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x = NULL, BOOL use_ellipses = FALSE, BOOL use_color = TRUE) const; S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const; S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 5ce1cbd63c..9ef019840a 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -68,7 +68,7 @@ LLButton::Params::Params() label_shadow("label_shadow", true), auto_resize("auto_resize", false), use_ellipses("use_ellipses", false), - use_font_color("use_font_color", false), + use_font_color("use_font_color", true), image_unselected("image_unselected"), image_selected("image_selected"), image_hover_selected("image_hover_selected"), diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index c47f4c60e3..bc9469cfad 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -890,7 +890,7 @@ void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y // font->renderUTF8(mLabel, 0, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/TRUE, /*use_color*/FALSE); + S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/TRUE); } void LLFolderViewItem::draw() @@ -999,7 +999,7 @@ void LLFolderViewItem::draw() { suffix_font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, &right_x, /*use_ellipses*/FALSE, /*use_color*/FALSE ); + S32_MAX, S32_MAX, &right_x); } //--------------------------------------------------------------------------------// @@ -1013,7 +1013,7 @@ void LLFolderViewItem::draw() F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; font->renderUTF8(combined_string, filter_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - filter_string_length, S32_MAX, &right_x, FALSE, FALSE); + filter_string_length, S32_MAX, &right_x); } else { @@ -1024,7 +1024,7 @@ void LLFolderViewItem::draw() F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; font->renderUTF8(mLabel, filter_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - label_filter_length, S32_MAX, &right_x, FALSE, FALSE); + label_filter_length, S32_MAX, &right_x); } S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length; @@ -1035,7 +1035,7 @@ void LLFolderViewItem::draw() F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; suffix_font->renderUTF8(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - suffix_filter_length, S32_MAX, &right_x, FALSE, FALSE); + suffix_filter_length, S32_MAX, &right_x); } } diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index bd6fd5b79e..e032b4b8c2 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -2107,7 +2107,7 @@ void LLLineEditor::draw() LLFontGL::NO_SHADOW, S32_MAX, mTextRightEdge - ll_round(rendered_pixels_right), - &rendered_pixels_right, FALSE); + &rendered_pixels_right); } // Draw children (border) LLView::draw(); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 7b6661a519..0afccef735 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1336,8 +1336,7 @@ void LLView::drawDebugRect() std::string debug_text = llformat("%s (%d x %d)", getName().c_str(), debug_rect.getWidth(), debug_rect.getHeight()); LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color, - LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); } } LLUI::popMatrix(); diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index abc5165f1e..ecfc4e7b41 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -102,11 +102,7 @@ public: LLFontGL::VCENTER, // valign LLFontGL::NORMAL, // style LLFontGL::DROP_SHADOW_SOFT, // shadow - mText.size(), // max_chars - S32_MAX, // max_pixels - nullptr, // right_x - false, // use_ellipses - true); // use_color + mText.size()); // max_chars } virtual void updatePanel(BOOL allow_modify) override {} @@ -144,11 +140,7 @@ public: LLFontGL::VCENTER, // valign LLFontGL::NORMAL, // style LLFontGL::DROP_SHADOW_SOFT, // shadow - 1, // max_chars - S32_MAX, // max_pixels - nullptr, // right_x - false, // use_ellipses - true); // use_color + 1); // max_chars } virtual void updatePanel(BOOL allow_modify) override {} @@ -225,10 +217,7 @@ protected: LLFontGL::NORMAL, // style LLFontGL::DROP_SHADOW_SOFT, // shadow 1, // max_chars - max_pixels, // max_pixels - nullptr, // right_x - false, // use_ellipses - true); // use_color + max_pixels); // max_pixels } void drawName(std::string name, F32 x, F32 y, S32 max_pixels, LLColor4& color) @@ -244,10 +233,7 @@ protected: LLFontGL::NORMAL, // style LLFontGL::DROP_SHADOW_SOFT, // shadow -1, // max_chars - max_pixels, // max_pixels - nullptr, // right_x - true, // use_ellipses - false); // use_color + max_pixels); // max_pixels } private: diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 6032064c31..db69c3e2c3 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -1601,7 +1601,7 @@ void LLOverlapPanel::draw() LLUI::translate(5,getRect().getHeight()-20); // translate to top-5,left-5 LLView::sDrawPreviewHighlights = FALSE; LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text, 0, 0, 0, text_color, - LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); } else { @@ -1619,7 +1619,7 @@ void LLOverlapPanel::draw() std::string current_selection = std::string(current_selection_text + LLView::sPreviewClickedElement->getName() + " (no elements overlap)"); S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(current_selection) + 10; LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection, 0, 0, 0, text_color, - LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); // widen panel enough to fit this text LLRect rect = getRect(); setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop)); @@ -1685,7 +1685,7 @@ void LLOverlapPanel::draw() // draw currently-selected element at top of overlappers LLUI::translate(0,-mSpacing); LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text + LLView::sPreviewClickedElement->getName(), 0, 0, 0, text_color, - LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); LLUI::translate(0,-mSpacing-LLView::sPreviewClickedElement->getRect().getHeight()); // skip spacing distance + height LLView::sPreviewClickedElement->draw(); @@ -1700,7 +1700,7 @@ void LLOverlapPanel::draw() // draw name LLUI::translate(0,-mSpacing); LLFontGL::getFontSansSerifSmall()->renderUTF8(overlapper_text + viewp->getName(), 0, 0, 0, text_color, - LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); // draw element LLUI::translate(0,-mSpacing-viewp->getRect().getHeight()); // skip spacing distance + height diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp index 46f455aede..e6e3a10e13 100644 --- a/indra/newview/llpanelemojicomplete.cpp +++ b/indra/newview/llpanelemojicomplete.cpp @@ -118,7 +118,7 @@ void LLPanelEmojiComplete::draw() LLWString text(1, mEmojis[curIdx].Character); mIconFont->render(text, 0, iconCenterX, iconCenterY, LLColor4::white, LLFontGL::HCENTER, LLFontGL::VCENTER, LLFontGL::NORMAL, - LLFontGL::DROP_SHADOW_SOFT, 1, S32_MAX, nullptr, false, true); + LLFontGL::DROP_SHADOW_SOFT, 1); if (mVertical) { const std::string& shortCode = mEmojis[curIdx].String; @@ -129,7 +129,7 @@ void LLPanelEmojiComplete::draw() std::string text = shortCode.substr(0, mEmojis[curIdx].Begin); mTextFont->renderUTF8(text, 0, x0, iconCenterY, LLColor4::white, LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - text.size(), x1, NULL, FALSE, FALSE); + text.size(), x1); x0 += mTextFont->getWidthF32(text); x1 = textLeft + textWidth - x0; } @@ -138,7 +138,7 @@ void LLPanelEmojiComplete::draw() std::string text = shortCode.substr(mEmojis[curIdx].Begin, mEmojis[curIdx].End - mEmojis[curIdx].Begin); mTextFont->renderUTF8(text, 0, x0, iconCenterY, LLColor4::yellow6, LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - text.size(), x1, NULL, FALSE, FALSE); + text.size(), x1); x0 += mTextFont->getWidthF32(text); x1 = textLeft + textWidth - x0; } @@ -147,7 +147,7 @@ void LLPanelEmojiComplete::draw() std::string text = shortCode.substr(mEmojis[curIdx].End); mTextFont->renderUTF8(text, 0, x0, iconCenterY, LLColor4::white, LLFontGL::LEFT, LLFontGL::VCENTER, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, - text.size(), x1, NULL, FALSE, FALSE); + text.size(), x1); } iconCenterY -= mEmojiHeight; } diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 1051194183..84cd6e2da7 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -588,8 +588,7 @@ void LLGLTexMemBar::draw() x_right = 550.0; LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP, - LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, - &x_right, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &x_right); F32Kilobits bandwidth(LLAppViewer::getTextureFetch()->getTextureBandwidth()); F32Kilobits max_bandwidth(gSavedSettings.getF32("ThrottleBandwidthKBPS")); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6de510bc11..47c7eed872 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -955,8 +955,7 @@ public: { const Line& line = *iter; LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor, - LLFontGL::LEFT, LLFontGL::TOP, - LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE); + LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW); } } diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index d597207859..a8676d2ad6 100755 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -520,8 +520,7 @@ void LLWorldMapView::draw() S32_MAX, //max_chars mMapScale, //max_pixels NULL, - /*use_ellipses*/TRUE, - /*use_color*/FALSE); + /*use_ellipses*/TRUE); } } } diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index fe74cea2f1..8a9d3b755e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -27,7 +27,7 @@ left_delta="110" name="preset_text" top="5" - width="120"> + width="320"> (None) -- cgit v1.3 From 7075717b7c4a57d6bef60697ee506096a7c1b1ab Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Wed, 7 Feb 2024 21:26:57 +0100 Subject: SL-20363 Add Advanced option 'Debug Unicode' --- indra/llcommon/llstring.cpp | 49 +++++++++ indra/llcommon/llstring.h | 1 + indra/llui/lllineeditor.cpp | 14 +++ indra/llui/lllineeditor.h | 112 +++++++++++---------- indra/llui/lltextbase.cpp | 24 +++++ indra/llui/lltextbase.h | 66 ++++++------ indra/llui/llview.cpp | 1 + indra/llui/llview.h | 3 + indra/newview/llviewermenu.cpp | 26 +++++ .../skins/default/xui/en/floater_im_session.xml | 2 +- indra/newview/skins/default/xui/en/menu_viewer.xml | 8 ++ 11 files changed, 218 insertions(+), 88 deletions(-) (limited to 'indra/llcommon/llstring.cpp') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 17d69351ec..ab34262515 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -623,6 +623,7 @@ std::string mbcsstring_makeASCII(const std::string& wstr) } return out_str; } + std::string utf8str_removeCRLF(const std::string& utf8str) { if (0 == utf8str.length()) @@ -644,6 +645,54 @@ std::string utf8str_removeCRLF(const std::string& utf8str) return out; } +std::string utf8str_showBytesUTF8(const std::string& utf8str) +{ + std::string result; + + bool in_sequence = false; + for (U8 byte : utf8str) + { + if (byte >= 0x80) // Part of an UTF-8 sequence + { + if (!in_sequence) // Start new UTF-8 sequence + { + if (!result.empty() && result.back() != ' ') + result += ' '; // Use space as separator between ASCII and UTF-8 + result += '['; + } + else if (byte >= 0xC0) // Start another UTF-8 sequence + { + result += "] ["; // Use space as separator between UTF-8 and UTF-8 + } + else // Continue the same UTF-8 sequence + { + result += '.'; + } + result += llformat("%02X", byte); // The byte is represented in hexadecimal form + in_sequence = true; + } + else // ASCII symbol is represented as a character + { + if (in_sequence) // End of UTF-8 sequence + { + result += ']'; + if (byte != ' ') + { + result += ' '; // Use space as separator between UTF-8 and ASCII + } + } + result += byte; + in_sequence = false; + } + } + if (in_sequence) // End of UTF-8 sequence + { + result += ']'; + } + + return result; +} + #if LL_WINDOWS unsigned int ll_wstring_default_code_page() { diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 8def59ed7f..38b9c3e23c 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -743,6 +743,7 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str); LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); +LL_COMMON_API std::string utf8str_showBytesUTF8(const std::string& utf8str); #if LL_WINDOWS /* @name Windows string helpers diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index e032b4b8c2..453fa29e7c 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1739,6 +1739,20 @@ void LLLineEditor::drawBackground() } } +//virtual +const std::string LLLineEditor::getToolTip() const +{ + if (sDebugUnicode) + { + std::string text = getText(); + std::string tooltip = utf8str_showBytesUTF8(text); + return tooltip; + } + + return LLUICtrl::getToolTip(); +} + +//virtual void LLLineEditor::draw() { F32 alpha = getDrawContext().mAlpha; diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 69eb0792e1..5794b3c35a 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -119,54 +119,55 @@ protected: friend class LLUICtrlFactory; friend class LLFloaterEditUI; void showContextMenu(S32 x, S32 y); + public: virtual ~LLLineEditor(); // mousehandler overrides - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); - /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); - /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); - /*virtual*/ void onMouseCaptureLost(); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask) override; + /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask) override; + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask) override; + /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char) override; + /*virtual*/ void onMouseCaptureLost() override; // LLEditMenuHandler overrides - virtual void cut(); - virtual BOOL canCut() const; - virtual void copy(); - virtual BOOL canCopy() const; - virtual void paste(); - virtual BOOL canPaste() const; + /*virtual*/ void cut() override; + /*virtual*/ BOOL canCut() const override; + /*virtual*/ void copy() override; + /*virtual*/ BOOL canCopy() const override; + /*virtual*/ void paste() override; + /*virtual*/ BOOL canPaste() const override; virtual void updatePrimary(); virtual void copyPrimary(); virtual void pastePrimary(); virtual BOOL canPastePrimary() const; - virtual void doDelete(); - virtual BOOL canDoDelete() const; + /*virtual*/ void doDelete() override; + /*virtual*/ BOOL canDoDelete() const override; - virtual void selectAll(); - virtual BOOL canSelectAll() const; + /*virtual*/ void selectAll() override; + /*virtual*/ BOOL canSelectAll() const override; - virtual void deselect(); - virtual BOOL canDeselect() const; + /*virtual*/ void deselect() override; + /*virtual*/ BOOL canDeselect() const override; // LLSpellCheckMenuHandler overrides - /*virtual*/ bool getSpellCheck() const; + /*virtual*/ bool getSpellCheck() const override; - /*virtual*/ const std::string& getSuggestion(U32 index) const; - /*virtual*/ U32 getSuggestionCount() const; - /*virtual*/ void replaceWithSuggestion(U32 index); + /*virtual*/ const std::string& getSuggestion(U32 index) const override; + /*virtual*/ U32 getSuggestionCount() const override; + /*virtual*/ void replaceWithSuggestion(U32 index) override; - /*virtual*/ void addToDictionary(); - /*virtual*/ bool canAddToDictionary() const; + /*virtual*/ void addToDictionary() override; + /*virtual*/ bool canAddToDictionary() const override; - /*virtual*/ void addToIgnore(); - /*virtual*/ bool canAddToIgnore() const; + /*virtual*/ void addToIgnore() override; + /*virtual*/ bool canAddToIgnore() const override; // Spell checking helper functions std::string getMisspelledWord(U32 pos) const; @@ -174,27 +175,28 @@ public: void onSpellCheckSettingsChange(); // view overrides - virtual void draw(); - virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE); - virtual void onFocusReceived(); - virtual void onFocusLost(); - virtual void setEnabled(BOOL enabled); + /*virtual*/ const std::string getToolTip() const override; + /*virtual*/ void draw() override; + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + /*virtual*/ void onFocusReceived() override; + /*virtual*/ void onFocusLost() override; + /*virtual*/ void setEnabled(BOOL enabled) override; // UI control overrides - virtual void clear(); - virtual void onTabInto(); - virtual void setFocus( BOOL b ); - virtual void setRect(const LLRect& rect); - virtual BOOL acceptsTextInput() const; - virtual void onCommit(); - virtual BOOL isDirty() const; // Returns TRUE if user changed value at all - virtual void resetDirty(); // Clear dirty state + /*virtual*/ void clear() override; + /*virtual*/ void onTabInto() override; + /*virtual*/ void setFocus(BOOL b) override; + /*virtual*/ void setRect(const LLRect& rect) override; + /*virtual*/ BOOL acceptsTextInput() const override; + /*virtual*/ void onCommit() override; + /*virtual*/ BOOL isDirty() const override; // Returns TRUE if user changed value at all + /*virtual*/ void resetDirty() override; // Clear dirty state // assumes UTF8 text - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; - virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); - virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); + /*virtual*/ void setValue(const LLSD& value) override; + /*virtual*/ LLSD getValue() const override; + /*virtual*/ BOOL setTextArg(const std::string& key, const LLStringExplicit& text) override; + /*virtual*/ BOOL setLabelArg(const std::string& key, const LLStringExplicit& text) override; void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; } const std::string& getLabel() { return mLabel.getString(); } @@ -216,7 +218,7 @@ public: // Selects characters 'start' to 'end'. void setSelection(S32 start, S32 end); - virtual void getSelectionRange(S32 *position, S32 *length) const; + /*virtual*/ void getSelectionRange(S32 *position, S32 *length) const override; void setCommitOnFocusLost( BOOL b ) { mCommitOnFocusLost = b; } void setRevertOnEsc( BOOL b ) { mRevertOnEsc = b; } @@ -315,14 +317,14 @@ public: void updateAllowingLanguageInput(); BOOL hasPreeditString() const; // Implementation (overrides) of LLPreeditor - virtual void resetPreedit(); - virtual void updatePreedit(const LLWString &preedit_string, - const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position); - virtual void markAsPreedit(S32 position, S32 length); - virtual void getPreeditRange(S32 *position, S32 *length) const; - virtual BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; - virtual S32 getPreeditFontSize() const; - virtual LLWString getPreeditString() const { return getWText(); } + /*virtual*/ void resetPreedit() override; + /*virtual*/ void updatePreedit(const LLWString &preedit_string, + const segment_lengths_t &preedit_segment_lengths, const standouts_t &preedit_standouts, S32 caret_position) override; + /*virtual*/ void markAsPreedit(S32 position, S32 length) override; + /*virtual*/ void getPreeditRange(S32 *position, S32 *length) const override; + /*virtual*/ BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const override; + /*virtual*/ S32 getPreeditFontSize() const override; + /*virtual*/ LLWString getPreeditString() const override { return getWText(); } void setText(const LLStringExplicit &new_text, bool use_size_limit); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8f628b4818..7ccf025a19 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1107,6 +1107,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) needsReflow(reflow_start_index); } +//virtual BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) { // handle triple click @@ -1161,6 +1162,7 @@ BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) return LLUICtrl::handleMouseDown(x, y, mask); } +//virtual BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1180,6 +1182,7 @@ BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask) return LLUICtrl::handleMouseUp(x, y, mask); } +//virtual BOOL LLTextBase::handleMiddleMouseDown(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1191,6 +1194,7 @@ BOOL LLTextBase::handleMiddleMouseDown(S32 x, S32 y, MASK mask) return LLUICtrl::handleMiddleMouseDown(x, y, mask); } +//virtual BOOL LLTextBase::handleMiddleMouseUp(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1202,6 +1206,7 @@ BOOL LLTextBase::handleMiddleMouseUp(S32 x, S32 y, MASK mask) return LLUICtrl::handleMiddleMouseUp(x, y, mask); } +//virtual BOOL LLTextBase::handleRightMouseDown(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1213,6 +1218,7 @@ BOOL LLTextBase::handleRightMouseDown(S32 x, S32 y, MASK mask) return LLUICtrl::handleRightMouseDown(x, y, mask); } +//virtual BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1224,6 +1230,7 @@ BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask) return LLUICtrl::handleRightMouseUp(x, y, mask); } +//virtual BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask) { //Don't start triple click timer if user have clicked on scrollbar @@ -1243,6 +1250,7 @@ BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask) return LLUICtrl::handleDoubleClick(x, y, mask); } +//virtual BOOL LLTextBase::handleHover(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1254,6 +1262,7 @@ BOOL LLTextBase::handleHover(S32 x, S32 y, MASK mask) return LLUICtrl::handleHover(x, y, mask); } +//virtual BOOL LLTextBase::handleScrollWheel(S32 x, S32 y, S32 clicks) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1265,6 +1274,7 @@ BOOL LLTextBase::handleScrollWheel(S32 x, S32 y, S32 clicks) return LLUICtrl::handleScrollWheel(x, y, clicks); } +//virtual BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); @@ -1276,7 +1286,20 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask) return LLUICtrl::handleToolTip(x, y, mask); } +//virtual +const std::string LLTextBase::getToolTip() const +{ + if (sDebugUnicode) + { + std::string text = getText(); + std::string tooltip = utf8str_showBytesUTF8(text); + return tooltip; + } + return LLUICtrl::getToolTip(); +} + +//virtual void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent) { if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape) @@ -1303,6 +1326,7 @@ void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent) } } +//virtual void LLTextBase::draw() { // reflow if needed, on demand diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 37ab798a1d..9d3c54fbee 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -285,7 +285,7 @@ typedef LLPointer LLTextSegmentPtr; /// as LLTextEditor and LLTextBox. It implements shared functionality /// such as Url highlighting and opening. /// -class LLTextBase +class LLTextBase : public LLUICtrl, protected LLEditMenuHandler, public LLSpellCheckMenuHandler, @@ -354,51 +354,52 @@ public: }; // LLMouseHandler interface - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) override; + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override; + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask) override; // LLView interface - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - /*virtual*/ void draw(); + /*virtual*/ const std::string getToolTip() const override; + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + /*virtual*/ void draw() override; // LLUICtrl interface - /*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; } - /*virtual*/ void setColor( const LLColor4& c ); + /*virtual*/ BOOL acceptsTextInput() const override { return !mReadOnly; } + /*virtual*/ void setColor(const LLColor4& c) override; virtual void setReadOnlyColor(const LLColor4 &c); - virtual void onVisibilityChange( BOOL new_visibility ); + /*virtual*/ void onVisibilityChange(BOOL new_visibility) override; - /*virtual*/ void setValue(const LLSD& value ); - /*virtual*/ LLTextViewModel* getViewModel() const; + /*virtual*/ void setValue(const LLSD& value) override; + /*virtual*/ LLTextViewModel* getViewModel() const override; // LLEditMenuHandler interface - /*virtual*/ BOOL canDeselect() const; - /*virtual*/ void deselect(); + /*virtual*/ BOOL canDeselect() const override; + /*virtual*/ void deselect() override; - virtual void onFocusReceived(); - virtual void onFocusLost(); + virtual void onFocusReceived() override; + virtual void onFocusLost() override; void setParseHTML(bool parse_html) { mParseHTML = parse_html; } // LLSpellCheckMenuHandler overrides - /*virtual*/ bool getSpellCheck() const; + /*virtual*/ bool getSpellCheck() const override; - /*virtual*/ const std::string& getSuggestion(U32 index) const; - /*virtual*/ U32 getSuggestionCount() const; - /*virtual*/ void replaceWithSuggestion(U32 index); + /*virtual*/ const std::string& getSuggestion(U32 index) const override; + /*virtual*/ U32 getSuggestionCount() const override; + /*virtual*/ void replaceWithSuggestion(U32 index) override; - /*virtual*/ void addToDictionary(); - /*virtual*/ bool canAddToDictionary() const; + /*virtual*/ void addToDictionary() override; + /*virtual*/ bool canAddToDictionary() const override; - /*virtual*/ void addToIgnore(); - /*virtual*/ bool canAddToIgnore() const; + /*virtual*/ void addToIgnore() override; + /*virtual*/ bool canAddToIgnore() const override; // Spell checking helper functions std::string getMisspelledWord(U32 pos) const; @@ -432,7 +433,7 @@ public: void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params()); void setLabel(const LLStringExplicit& label); - virtual BOOL setLabelArg(const std::string& key, const LLStringExplicit& text ); + /*virtual*/ BOOL setLabelArg(const std::string& key, const LLStringExplicit& text) override; const std::string& getLabel() { return mLabel.getString(); } const LLWString& getWlabel() { return mLabel.getWString();} @@ -649,7 +650,8 @@ protected: S32 normalizeUri(std::string& uri); protected: - virtual std::string _getSearchText() const + // virtual + std::string _getSearchText() const override { return mLabel.getString() + getToolTip(); } diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 0afccef735..139eb17efa 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -60,6 +60,7 @@ static const S32 LINE_HEIGHT = 15; S32 LLView::sDepth = 0; bool LLView::sDebugRects = false; +bool LLView::sDebugUnicode = false; bool LLView::sIsRectDirty = false; LLRect LLView::sDirtyRect; bool LLView::sDebugRectsShowNames = true; diff --git a/indra/llui/llview.h b/indra/llui/llview.h index b498451dce..6e16d41cba 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -659,6 +659,9 @@ public: // Draw debug rectangles around widgets to help with alignment and spacing static bool sDebugRects; + // Show hexadecimal byte values of unicode symbols in a tooltip + static bool sDebugUnicode; + static bool sIsRectDirty; static LLRect sDirtyRect; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8419555445..2cf341f87f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1437,6 +1437,30 @@ class LLAdvancedCheckDebugViews : public view_listener_t +/////////////////// +// DEBUG UNICODE // +/////////////////// + + +class LLAdvancedToggleDebugUnicode : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLView::sDebugUnicode = !(LLView::sDebugUnicode); + return true; + } +}; + +class LLAdvancedCheckDebugUnicode : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return LLView::sDebugUnicode; + } +}; + + + /////////////////////// // XUI NAME TOOLTIPS // /////////////////////// @@ -9509,6 +9533,8 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks"); view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews"); view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews"); + view_listener_t::addMenu(new LLAdvancedCheckDebugUnicode(), "Advanced.CheckDebugUnicode"); + view_listener_t::addMenu(new LLAdvancedToggleDebugUnicode(), "Advanced.ToggleDebugUnicode"); view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips"); view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips"); view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents"); diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index c3e002e97d..1b6bc7025a 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -288,7 +288,7 @@ expand_lines_count="5" follows="left|right|bottom" font="SansSerifSmall" - height="20" + height="20" is_expandable="true" text_tentative_color="TextFgTentativeColor" bg_writeable_color="ScriptBackground" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 171c0f4f6d..38763cd9a8 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3610,6 +3610,14 @@ function="World.EnvPreset" + + + + -- cgit v1.3 From afc9252372b2b511bb3f7caaaa0856989bbd3f46 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Thu, 8 Feb 2024 21:55:59 +0100 Subject: SL-20363 Option 'Debug Unicode' - show unicode values --- indra/llcommon/llstring.cpp | 87 +++++++++++++++++++++++++++++++++++++++------ indra/llcommon/llstring.h | 2 ++ 2 files changed, 78 insertions(+), 11 deletions(-) (limited to 'indra/llcommon/llstring.cpp') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index ab34262515..82dc7c9f80 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -645,49 +645,114 @@ std::string utf8str_removeCRLF(const std::string& utf8str) return out; } +llwchar utf8str_to_wchar(const std::string& utf8str, size_t offset, size_t length) +{ + switch (length) + { + case 2: + return ((utf8str[offset] & 0x1F) << 6) + + (utf8str[offset + 1] & 0x3F); + case 3: + return ((utf8str[offset] & 0x0F) << 12) + + ((utf8str[offset + 1] & 0x3F) << 6) + + (utf8str[offset + 2] & 0x3F); + case 4: + return ((utf8str[offset] & 0x07) << 18) + + ((utf8str[offset + 1] & 0x3F) << 12) + + ((utf8str[offset + 2] & 0x3F) << 6) + + (utf8str[offset + 3] & 0x3F); + case 5: + return ((utf8str[offset] & 0x03) << 24) + + ((utf8str[offset + 1] & 0x3F) << 18) + + ((utf8str[offset + 2] & 0x3F) << 12) + + ((utf8str[offset + 3] & 0x3F) << 6) + + (utf8str[offset + 4] & 0x3F); + case 6: + return ((utf8str[offset] & 0x01) << 30) + + ((utf8str[offset + 1] & 0x3F) << 24) + + ((utf8str[offset + 2] & 0x3F) << 18) + + ((utf8str[offset + 3] & 0x3F) << 12) + + ((utf8str[offset + 4] & 0x3F) << 6) + + (utf8str[offset + 5] & 0x3F); + case 7: + return ((utf8str[offset + 1] & 0x03) << 30) + + ((utf8str[offset + 2] & 0x3F) << 24) + + ((utf8str[offset + 3] & 0x3F) << 18) + + ((utf8str[offset + 4] & 0x3F) << 12) + + ((utf8str[offset + 5] & 0x3F) << 6) + + (utf8str[offset + 6] & 0x3F); + } + return LL_UNKNOWN_CHAR; +} + std::string utf8str_showBytesUTF8(const std::string& utf8str) { std::string result; bool in_sequence = false; - for (U8 byte : utf8str) + size_t sequence_size = 0; + size_t byte_index = 0; + size_t source_length = utf8str.size(); + + auto open_sequence = [&]() + { + if (!result.empty() && result.back() != '\n') + result += '\n'; // Use LF as a separator before new UTF-8 sequence + result += '['; + in_sequence = true; + }; + + auto close_sequence = [&]() + { + llwchar unicode = utf8str_to_wchar(utf8str, byte_index - sequence_size, sequence_size); + if (unicode != LL_UNKNOWN_CHAR) + { + result += llformat("+%04X", unicode); + } + result += ']'; + in_sequence = false; + sequence_size = 0; + }; + + while (byte_index < source_length) { + U8 byte = utf8str[byte_index]; if (byte >= 0x80) // Part of an UTF-8 sequence { if (!in_sequence) // Start new UTF-8 sequence { - if (!result.empty() && result.back() != ' ') - result += ' '; // Use space as separator between ASCII and UTF-8 - result += '['; + open_sequence(); } else if (byte >= 0xC0) // Start another UTF-8 sequence { - result += "] ["; // Use space as separator between UTF-8 and UTF-8 + close_sequence(); + open_sequence(); } else // Continue the same UTF-8 sequence { result += '.'; } result += llformat("%02X", byte); // The byte is represented in hexadecimal form - in_sequence = true; + ++sequence_size; } else // ASCII symbol is represented as a character { if (in_sequence) // End of UTF-8 sequence { - result += ']'; - if (byte != ' ') + close_sequence(); + if (byte != '\n') { - result += ' '; // Use space as separator between UTF-8 and ASCII + result += '\n'; // Use LF as a separator between UTF-8 and ASCII } } result += byte; - in_sequence = false; } + ++byte_index; } + if (in_sequence) // End of UTF-8 sequence { - result += ']'; + close_sequence(); } return result; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 38b9c3e23c..bfbf25d9ab 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -743,6 +743,8 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str); LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); +LL_COMMON_API llwchar utf8str_to_wchar(const std::string& utf8str, size_t offset, size_t length); + LL_COMMON_API std::string utf8str_showBytesUTF8(const std::string& utf8str); #if LL_WINDOWS -- cgit v1.3