// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position. // Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for // the simple reasons that intermediate states may be invalid even if the final result is valid. // bool validateFloat(const LLWString &str) { LLLocale locale(LLLocale::USER_LOCALE); bool success = TRUE; LLWString trimmed = str; LLWStringUtil::trim(trimmed); S32 len = trimmed.length(); if( 0 < len ) { // May be a comma or period, depending on the locale llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint(); S32 i = 0; // First character can be a negative sign if( '-' == trimmed[0] ) { i++; } for( ; i < len; i++ ) { if( (decimal_point != trimmed[i] ) && !LLStringOps::isDigit( trimmed[i] ) ) { success = FALSE; break; } } } return success; }
// Limits what characters can be used to [1234567890-] with [-] only valid in the first position. // Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for // the simple reasons that intermediate states may be invalid even if the final result is valid. // bool validateInt(const LLWString &str) { LLLocale locale(LLLocale::USER_LOCALE); bool success = TRUE; LLWString trimmed = str; LLWStringUtil::trim(trimmed); S32 len = trimmed.length(); if( 0 < len ) { S32 i = 0; // First character can be a negative sign if( '-' == trimmed[0] ) { i++; } for( ; i < len; i++ ) { if( !LLStringOps::isDigit( trimmed[i] ) ) { success = FALSE; break; } } } return success; }
bool validateNonNegativeS32(const LLWString &str) { LLLocale locale(LLLocale::USER_LOCALE); LLWString trimmed = str; LLWStringUtil::trim(trimmed); S32 len = trimmed.length(); bool success = TRUE; if(0 < len) { if('-' == trimmed[0]) { success = FALSE; } S32 i = 0; while(success && (i < len)) { if(!LLStringOps::isDigit(trimmed[i++])) { success = FALSE; } } } if (success) { S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10); if (val < 0) { success = FALSE; } } return success; }
// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. // Otherwise returns input and channel 0. LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) { if (mesg[0] == '/' && mesg[1] == '/') { // This is a "repeat channel send" *channel = mLastSpecialChatChannel; return mesg.substr(2, mesg.length() - 2); } else if (mesg[0] == '/' && mesg[1] && ( LLStringOps::isDigit(mesg[1]) // <edit> || mesg[1] == '-' )) // </edit> { // This a special "/20" speak on a channel S32 pos = 0; // <edit> if(mesg[1] == '-') pos++; // </edit> // Copy the channel number into a string LLWString channel_string; llwchar c; do { c = mesg[pos+1]; channel_string.push_back(c); pos++; } while(c && pos < 64 && LLStringOps::isDigit(c)); // Move the pointer forward to the first non-whitespace char // Check isspace before looping, so we can handle "/33foo" // as well as "/33 foo" while(c && iswspace(c)) { c = mesg[pos+1]; pos++; } mLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); // <edit> if(mesg[1] == '-') mLastSpecialChatChannel = -mLastSpecialChatChannel; // </edit> *channel = mLastSpecialChatChannel; return mesg.substr(pos, mesg.length() - pos); } else { // This is normal chat. *channel = 0; return mesg; } }
bool GrowlManager::onLLNotification(const LLSD& notice) { if (notice["sigtype"].asString() != "add") { return false; } LLNotificationPtr notification = LLNotifications::instance().find(notice["id"].asUUID()); std::string name = notification->getName(); LLSD substitutions = notification->getSubstitutions(); if (gGrowlManager->mNotifications.find(name) != gGrowlManager->mNotifications.end()) { GrowlNotification* growl_notification = &gGrowlManager->mNotifications[name]; std::string body = ""; std::string title = ""; if (growl_notification->useDefaultTextForTitle) { title = notification->getMessage(); } else if (!growl_notification->growlTitle.empty()) { title = growl_notification->growlTitle; LLStringUtil::format(title, substitutions); } if (growl_notification->useDefaultTextForBody) { body = notification->getMessage(); } else if (!growl_notification->growlBody.empty()) { body = growl_notification->growlBody; LLStringUtil::format(body, substitutions); } //TM:FS no need to log whats sent to growl //LL_INFOS("GrowlLLNotification") << "Notice: " << title << ": " << body << LL_ENDL; if (name == "ObjectGiveItem" || name == "OwnObjectGiveItem" || name == "ObjectGiveItemUnknownUser" || name == "UserGiveItem" || name == "SystemMessageTip") { LLUrlMatch urlMatch; LLWString newLine = utf8str_to_wstring(body); LLWString workLine = utf8str_to_wstring(body); while (LLUrlRegistry::instance().findUrl(workLine, urlMatch) && !urlMatch.getUrl().empty()) { LLWStringUtil::replaceString(newLine, utf8str_to_wstring(urlMatch.getUrl()), utf8str_to_wstring(urlMatch.getLabel())); // Remove the URL from the work line so we don't end in a loop in case of regular URLs! // findUrl will always return the very first URL in a string workLine = workLine.erase(0, urlMatch.getEnd() + 1); } body = wstring_to_utf8str(newLine); } gGrowlManager->notify(title, body, growl_notification->growlName); } return false; }
void LLFixedBuffer::addLine(const LLWString& line) { if (line.empty()) { return; } removeExtraLines(); mLines.push_back(line); mLineLengths.push_back((S32)line.length()); mAddTimes.push_back(mTimer.getElapsedTimeF32()); }
// <dogmode> void LLChatBar::sendChat( EChatType type ) { if (mInputEditor) { LLWString text = mInputEditor->getConvertedText(); if (!text.empty()) { // store sent line in history, duplicates will get filtered if (mInputEditor) mInputEditor->updateHistory(); S32 channel = 0; stripChannelNumber(text, &channel); std::string utf8text = wstring_to_utf8str(text);//+" and read is "+llformat("%f",readChan)+" and undone is "+llformat("%d",undoneChan)+" but actualy channel is "+llformat("%d",channel); // Try to trigger a gesture, if not chat to a script. std::string utf8_revised_text; if (0 == channel) { convert_roleplay_text(utf8text); // discard returned "found" boolean LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); } else { utf8_revised_text = utf8text; } utf8_revised_text = utf8str_trim(utf8_revised_text); EChatType nType(type == CHAT_TYPE_OOC ? CHAT_TYPE_NORMAL : type); if (!utf8_revised_text.empty() && cmd_line_chat(utf8_revised_text, nType)) { // Chat with animation #if SHY_MOD //Command handler if(!SHCommandHandler::handleCommand(true, utf8_revised_text, gAgentID, (LLViewerObject*)gAgentAvatarp))//returns true if handled #endif //shy_mod sendChatFromViewer(utf8_revised_text, nType, TRUE); } } } childSetValue("Chat Editor", LLStringUtil::null); gAgent.stopTyping(); // If the user wants to stop chatting on hitting return, lose focus // and go out of chat mode. if (gChatBar == this && gSavedSettings.getBOOL("CloseChatOnReturn")) { stopChat(); } }
virtual BOOL execute( LLTextEditor* editor, S32* delta ) { LLViewerTextEditor* viewer_editor = (LLViewerTextEditor*)editor; // Take this opportunity to remove any unused embedded items from this editor viewer_editor->mEmbeddedItemList->removeUnusedChars(); if(viewer_editor->mEmbeddedItemList->insertEmbeddedItem( mItem, &mExtCharValue, true ) ) { LLWString ws; ws.assign(1, mExtCharValue); *delta = insert(editor, getPosition(), ws ); return (*delta != 0); } return FALSE; }
void LLViewerTextEditor::setEmbeddedText(const std::string& instr) { LLWString wtext = utf8str_to_wstring(instr); for (S32 i=0; i<(S32)wtext.size(); i++) { llwchar wch = wtext[i]; if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) { S32 index = wch - FIRST_EMBEDDED_CHAR; wtext[i] = mEmbeddedItemList->getEmbeddedCharFromIndex(index); } } setWText(wtext); }
void LLNearbyChatBar::sendChat( EChatType type ) { if (mChatBox) { LLWString text = mChatBox->getConvertedText(); if (!text.empty()) { // store sent line in history, duplicates will get filtered mChatBox->updateHistory(); // Check if this is destined for another channel S32 channel = 0; stripChannelNumber(text, &channel); std::string utf8text = wstring_to_utf8str(text); // Try to trigger a gesture, if not chat to a script. std::string utf8_revised_text; if (0 == channel) { // discard returned "found" boolean LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); } else { utf8_revised_text = utf8text; } utf8_revised_text = utf8str_trim(utf8_revised_text); type = processChatTypeTriggers(type, utf8_revised_text); if (!utf8_revised_text.empty()) { // Chat with animation sendChatFromViewer(utf8_revised_text, type, TRUE); } } mChatBox->setText(LLStringExplicit("")); } gAgent.stopTyping(); // If the user wants to stop chatting on hitting return, lose focus // and go out of chat mode. if (gSavedSettings.getBOOL("CloseChatOnReturn")) { stopChat(); } }
void LLChatBar::sendChat( EChatType type ) { if (mInputEditor) { LLWString text = mInputEditor->getConvertedText(); if (!text.empty()) { // store sent line in history, duplicates will get filtered if (mInputEditor) mInputEditor->updateHistory(); // Check if this is destined for another channel S32 channel = mChanCtrlEnabled ? (S32)(mChannelControl->get()) : 0; stripChannelNumber(text, &channel); std::string utf8text = wstring_to_utf8str(text); // Try to trigger a gesture, if not chat to a script. std::string utf8_revised_text; if (0 == channel) { // discard returned "found" boolean gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text); } else { utf8_revised_text = utf8text; } utf8_revised_text = utf8str_trim(utf8_revised_text); if (!utf8_revised_text.empty()) { // Chat with animation sendChatFromViewer(utf8_revised_text, type, TRUE); } } } childSetValue("Chat Editor", LLStringUtil::null); gAgent.stopTyping(); // If the user wants to stop chatting on hitting return, lose focus // and go out of chat mode. if (gChatBar == this && gSavedSettings.getBOOL("CloseChatOnReturn")) { stopChat(); } }
// Used for most names of things stored on the server, due to old file-formats // that used the pipe (|) for multiline text storage. Examples include // inventory item names, parcel names, object names, etc. bool validateASCIIPrintableNoPipe(const LLWString &str) { bool rv = TRUE; S32 len = str.length(); if(len == 0) return rv; while(len--) { llwchar wc = str[len]; if (wc < 0x20 || wc > 0x7f || wc == '|') { rv = FALSE; break; } if(!(wc == ' ' || LLStringOps::isAlnum((char)wc) || LLStringOps::isPunct((char)wc) ) ) { rv = FALSE; break; } } return rv; }
void LLFloaterIMPanel::sendMsg() { if (!gAgent.isGodlike() && (mDialog == IM_NOTHING_SPECIAL) && mOtherParticipantUUID.isNull()) { llinfos << "Cannot send IM to everyone unless you're a god." << llendl; return; } if (mInputEditor) { LLWString text = mInputEditor->getConvertedText(); if(!text.empty()) { // store sent line in history, duplicates will get filtered if (mInputEditor) mInputEditor->updateHistory(); // Truncate and convert to UTF8 for transport std::string utf8_text = wstring_to_utf8str(text); utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); if ( mSessionInitialized ) { LLIMModel::sendMessage(utf8_text, mSessionUUID, mOtherParticipantUUID, mDialog); } else { //queue up the message to send once the session is //initialized mQueuedMsgsForInit.append(utf8_text); } } LLViewerStats::getInstance()->incStat(LLViewerStats::ST_IM_COUNT); mInputEditor->setText(LLStringUtil::null); } // Don't need to actually send the typing stop message, the other // client will infer it from receiving the message. mTyping = FALSE; mSentTypingState = TRUE; }
void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width) { if (max_width < 0.0) { max_width = (F32)getRect().getWidth(); } LLWString wtext = utf8str_to_wstring(in_text); LLWString final_wtext; LLWString::size_type cur = 0;; LLWString::size_type len = wtext.size(); while (cur < len) { LLWString::size_type end = wtext.find('\n', cur); if (end == LLWString::npos) { end = len; } LLWString::size_type runLen = end - cur; if (runLen > 0) { LLWString run(wtext, cur, runLen); LLWString::size_type useLen = mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE); final_wtext.append(wtext, cur, useLen); cur += useLen; } if (cur < len) { if (wtext[cur] == '\n') { cur += 1; } final_wtext += '\n'; } } std::string final_text = wstring_to_utf8str(final_wtext); setText(final_text); }
void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos) { static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace"); if(perform_autoreplace) { S32 wordEnd = cursorPos-1; LLWString text = inputText.getWString(); bool atSpace = (text[wordEnd] == ' '); bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd])); if (atSpace || haveWord) { if (atSpace && wordEnd > 0) { // find out if this space immediately follows a word wordEnd--; haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd])); } if (haveWord) { // wordEnd points to the end of a word, now find the start of the word std::string word; S32 wordStart = wordEnd; for ( S32 backOne = wordStart - 1; backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]); backOne-- ) { wordStart--; // walk wordStart back to the beginning of the word } LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL; std::string strText = std::string(text.begin(), text.end()); std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1); std::string replacementWord( mSettings.replaceWord( lastWord ) ); if ( replacementWord != lastWord ) { // The last word is one for which we have a replacement if (atSpace) { // replace the last word in the input LLWString strNew = utf8str_to_wstring(replacementWord); LLWString strOld = utf8str_to_wstring(lastWord); int size_change = strNew.size() - strOld.size(); text.replace(wordStart,lastWord.length(),strNew); inputText = wstring_to_utf8str(text); cursorPos+=size_change; } } } } } }
bool LLUrlRegistry::isUrl(const LLWString &text) { LLUrlMatch match; if (findUrl(text, match)) { return (match.getStart() == 0 && match.getEnd() >= text.size()-1); } return false; }
bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName) { bool added = false; if ( ! keyword.empty() && ! replacement.empty() ) { bool isOneWord = true; for (S32 character = 0; isOneWord && character < keyword.size(); character++ ) { if ( ! LLWStringUtil::isPartOfWord(keyword[character]) ) { LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "<<keyword.size()<<" '"<<character<<"')" << LL_ENDL; isOneWord = false; } } if ( isOneWord ) { bool listFound = false; for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray(); ! listFound && list != endLists; list++ ) { if ( listNameMatches(*list, listName) ) { listFound = true; (*list)[AUTOREPLACE_LIST_REPLACEMENTS][wstring_to_utf8str(keyword)]=wstring_to_utf8str(replacement); } } if (listFound) { added = true; } else { LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL; } } } return added; }
// Add the input uuid to the LL clipboard // Convert the uuid to string and concatenate that string to the system clipboard if legit bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type) { bool res = false; if (src.notNull()) { res = true; if (LLAssetType::lookupIsAssetIDKnowable(type)) { LLWString source = utf8str_to_wstring(src.asString()); res = addToClipboard(source, 0, source.size()); } if (res) { mObjects.push_back(src); mGeneration++; } } return res; }
void LLIMFloater::sendMsg() { if (!gAgent.isGodlike() && (mDialog == IM_NOTHING_SPECIAL) && mOtherParticipantUUID.isNull()) { llinfos << "Cannot send IM to everyone unless you're a god." << llendl; return; } if (mInputEditor) { LLWString text = mInputEditor->getConvertedText(); if(!text.empty()) { // Truncate and convert to UTF8 for transport std::string utf8_text = wstring_to_utf8str(text); utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); if (mSessionInitialized) { LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID,mDialog); } else { //queue up the message to send once the session is initialized mQueuedMsgsForInit.append(utf8_text); } mInputEditor->setText(LLStringUtil::null); updateMessages(); } else if (gSavedSettings.getBOOL("CloseIMOnEmptyReturn")) { // Close if we're the child of a floater closeFloater(); } } }
void LLViewerTextEditor::setASCIIEmbeddedText(const std::string& instr) { LLWString wtext; const U8* buffer = (U8*)(instr.c_str()); while (*buffer) { llwchar wch; U8 c = *buffer++; if (c >= 0x80) { S32 index = (S32)(c - 0x80); wch = mEmbeddedItemList->getEmbeddedCharFromIndex(index); } else { wch = (llwchar)c; } wtext.push_back(wch); } setWText(wtext); }
void DOHexEditor::copy() { if(!canCopy()) return; std::string text; if(mInData) { U32 start = getProperSelectionStart(); U32 end = getProperSelectionEnd(); for(U32 i = start; i < end; i++) text.append(llformat("%02X", mValue[i])); } else { U32 start = getProperSelectionStart(); U32 end = getProperSelectionEnd(); for(U32 i = start; i < end; i++) text.append(llformat("%c", mValue[i])); } LLWString wtext = utf8str_to_wstring(text); gClipboard.copyFromSubstring(wtext, 0, wtext.length()); }
std::string LLViewerTextEditor::getEmbeddedText() { #if 1 // New version (Version 2) mEmbeddedItemList->copyUsedCharsToIndexed(); LLWString outtextw; for (S32 i=0; i<(S32)getWText().size(); i++) { llwchar wch = getWChar(i); if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) { S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); wch = FIRST_EMBEDDED_CHAR + index; } outtextw.push_back(wch); } std::string outtext = wstring_to_utf8str(outtextw); return outtext; #else // Old version (Version 1) mEmbeddedItemList->copyUsedCharsToIndexed(); std::string outtext; for (S32 i=0; i<(S32)mWText.size(); i++) { llwchar wch = mWText[i]; if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) { S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); wch = 0x80 | index % 128; } else if (wch >= 0x80) { wch = LL_UNKNOWN_CHAR; } outtext.push_back((U8)wch); } return outtext; #endif }
// Checked: 2011-05-26 (RLVa-1.3.1c) | Added: RLVa-1.3.1c void RlvFloaterBehaviours::onBtnCopyToClipboard() const { std::ostringstream strRestrictions; strRestrictions << RlvStrings::getVersion() << "\n"; const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap(); for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj) { strRestrictions << "\n" << rlvGetItemNameFromObjID(itObj->first) << ":\n"; const rlv_command_list_t* pCommands = itObj->second.getCommandList(); for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd) { std::string strOption; LLUUID idOption; if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) ) { LLAvatarName avName; if (gObjectList.findObject(idOption)) strOption = rlvGetItemNameFromObjID(idOption, true); else if (LLAvatarNameCache::get(idOption, &avName)) strOption = (!avName.getAccountName().empty()) ? avName.getAccountName() : avName.getDisplayName(); else if (!gCacheName->getGroupName(idOption, strOption)) strOption = itCmd->getOption(); } strRestrictions << " -> " << itCmd->asString(); if ( (!strOption.empty()) && (strOption != itCmd->getOption()) ) strRestrictions << " [" << strOption << "]"; if (RLV_RET_SUCCESS != itCmd->getReturnType()) strRestrictions << " (" << RlvStrings::getStringFromReturnCode(itCmd->getReturnType()) << ")"; strRestrictions << "\n"; } } LLWString wstrRestrictions = utf8str_to_wstring(strRestrictions.str()); gClipboard.copyFromSubstring(wstrRestrictions, 0, wstrRestrictions.length()); }
bool validateASCII(const LLWString &str) { bool rv = TRUE; S32 len = str.length(); while(len--) { if (str[len] < 0x20 || str[len] > 0x7f) { rv = FALSE; break; } } return rv; }
// Used for multiline text stored on the server. // Example is landmark description in Places SP. bool validateASCIIWithNewLine(const LLWString &str) { bool rv = TRUE; S32 len = str.length(); while(len--) { if ((str[len] < 0x20 && str[len] != 0xA) || str[len] > 0x7f) { rv = FALSE; break; } } return rv; }
void LLHUDText::addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style, const LLFontGL* font) { LLWString wline = utf8str_to_wstring(text_utf8); if (!wline.empty()) { // use default font for segment if custom font not specified if (!font) { font = mFontp; } typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; LLWString seps(utf8str_to_wstring("\r\n")); boost::char_separator<llwchar> sep(seps.c_str()); tokenizer tokens(wline, sep); tokenizer::iterator iter = tokens.begin(); while (iter != tokens.end()) { U32 line_length = 0; do { F32 max_pixels = HUD_TEXT_MAX_WIDTH_NO_BUBBLE; S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); mTextSegments.push_back(segment); line_length += segment_length; } while (line_length != iter->size()); ++iter; } } }
bool validateAlphaNumSpace(const LLWString &str) { LLLocale locale(LLLocale::USER_LOCALE); bool rv = TRUE; S32 len = str.length(); if(len == 0) return rv; while(len--) { if(!(LLStringOps::isAlnum((char)str[len]) || (' ' == str[len]))) { rv = FALSE; break; } } return rv; }
void LLConsole::addQueuedLines() { for (line_queue_t::iterator iter = mLineQueue.begin(); iter != mLineQueue.end(); ++iter) { LineInfo& line_info = *iter; LLWString wline = line_info.wline; //F32 size = line_info.size; LLColor4 color = line_info.color; if (!wline.empty() && mFont != NULL) { // Wrap lines that are longer than the view is wide. S32 offset = 0; while( offset < (S32)wline.length() ) { S32 skip_chars; // skip '\n' // Figure out if a word-wrapped line fits here. LLWString::size_type line_end = wline.find_first_of(llwchar('\n'), offset); if (line_end != LLWString::npos) { skip_chars = 1; // skip '\n' } else { line_end = wline.size(); skip_chars = 0; } U32 drawable = mFont->maxDrawableChars(wline.c_str()+offset, (F32)mRect.getWidth(), line_end-offset, TRUE); if (drawable != 0) { LLFixedBuffer::addLine(wline.substr(offset, drawable)); mAddTimes[mAddTimes.size()-1] = line_info.add_time; } else { // force a blank line LLFixedBuffer::addLine(" "); } mColors.push_back(color); offset += (drawable + skip_chars); } } } mLineQueue.clear(); }
// static LLRect LLNotifyBox::getNotifyTipRect(const std::string &utf8message) { LLWString message = utf8str_to_wstring(utf8message); S32 message_len = message.length(); const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth"); // Make room for the icon area. const S32 text_area_width = NOTIFY_WIDTH - HPAD * 4 - 32; const llwchar* wchars = message.c_str(); const llwchar* start = wchars; const llwchar* end; S32 total_drawn = 0; bool done = false; S32 line_count; for (line_count = 2; !done; ++line_count) { for (end = start; *end != 0 && *end != '\n'; end++); if (*end == 0) { end = wchars + message_len; done = true; } for (S32 remaining = end - start; remaining;) { S32 drawn = sFont->maxDrawableChars(start, (F32)text_area_width, remaining, LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); if (0 == drawn) { drawn = 1; // Draw at least one character, even if it doesn't all fit. (avoids an infinite loop) } total_drawn += drawn; start += drawn; remaining -= drawn; if (total_drawn < message_len) { if (wchars[ total_drawn ] != '\n') { // wrap because line was too long line_count++; } } else { done = true; } } total_drawn++; // for '\n' start = ++end; } const S32 MIN_NOTIFY_HEIGHT = 72; const S32 MAX_NOTIFY_HEIGHT = 600; S32 notify_height = llceil((F32) (line_count+1) * sFont->getLineHeight()); if (gOverlayBar) { notify_height += gOverlayBar->getBoundingRect().mTop; } else { // *FIX: this is derived from the padding caused by the // rounded rects, shouldn't be a const here. notify_height += 10; } notify_height += VPAD; notify_height = llclamp(notify_height, MIN_NOTIFY_HEIGHT, MAX_NOTIFY_HEIGHT); const S32 RIGHT = gNotifyBoxView->getRect().getWidth(); const S32 LEFT = RIGHT - NOTIFY_WIDTH; // Make sure it goes slightly offscreen return LLRect(LEFT, notify_height-1, RIGHT, -1); }
F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidthF32(wtext.c_str(), begin_offset, max_chars); }