summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llmd5.cpp551
-rw-r--r--indra/llcommon/llmd5.h82
-rw-r--r--indra/llrender/llfontvertexbuffer.cpp2
-rw-r--r--indra/llui/lllineeditor.cpp60
-rw-r--r--indra/llui/lllineeditor.h5
-rw-r--r--indra/llui/lltextbase.cpp172
-rw-r--r--indra/llui/lltextbase.h9
-rw-r--r--indra/llui/llviewmodel.cpp10
-rw-r--r--indra/llui/llviewmodel.h4
-rw-r--r--indra/newview/llpanelmaininventory.cpp102
-rw-r--r--indra/newview/llpanelmaininventory.h5
-rw-r--r--indra/newview/skins/default/textures/map_avatar_you_32.tgabin3395 -> 4140 bytes
12 files changed, 578 insertions, 424 deletions
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index f64f54c262..e999b8f597 100644
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
@@ -68,10 +68,6 @@ documentation and/or software.
*/
-
-
-
-
#include "linden_common.h"
#include "llmd5.h"
@@ -81,232 +77,203 @@ documentation and/or software.
// how many bytes to grab at a time when checking files
const int LLMD5::BLOCK_LEN = 4096;
-
// LLMD5 simple initialization method
-
LLMD5::LLMD5()
{
- init();
+ init();
}
-
-
-
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block, and updating the
// context.
+void LLMD5::update(const uint8_t* input, const size_t input_length)
+{
+ size_t input_index, buffer_index;
+ size_t buffer_space; // how much space is left in buffer
-void LLMD5::update (const uint8_t *input, const size_t input_length) {
-
- size_t input_index, buffer_index;
- size_t buffer_space; // how much space is left in buffer
-
- if (finalized){ // so we can't update!
- std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl;
- return;
- }
-
- // Compute number of bytes mod 64
- buffer_index = size_t((count >> 3) & 0x3F);
+ if (finalized)
+ { // so we can't update!
+ std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl;
+ return;
+ }
- // Update number of bits
- count += input_length << 3;
+ // Compute number of bytes mod 64
+ buffer_index = size_t((count >> 3) & 0x3F);
- buffer_space = 64 - buffer_index; // how much space is left in buffer
+ // Update number of bits
+ count += input_length << 3;
- // now, transform each 64-byte piece of the input, bypassing the buffer
- if (input == NULL || input_length == 0){
- std::cerr << "LLMD5::update: Invalid input!" << std::endl;
- return;
- }
+ buffer_space = 64 - buffer_index; // how much space is left in buffer
- // Transform as many times as possible.
- if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
- // fill the rest of the buffer and transform
- memcpy( /* Flawfinder: ignore */
- buffer + buffer_index,
- input,
- buffer_space);
- transform (buffer);
+ // now, transform each 64-byte piece of the input, bypassing the buffer
+ if (input == NULL || input_length == 0)
+ {
+ std::cerr << "LLMD5::update: Invalid input!" << std::endl;
+ return;
+ }
- for (input_index = buffer_space; input_index + 63 < input_length;
- input_index += 64)
- transform (input+input_index);
+ // Transform as many times as possible.
+ if (input_length >= buffer_space) // ie. we have enough to fill the buffer
+ {
+ // fill the rest of the buffer and transform
+ memcpy(/* Flawfinder: ignore */
+ buffer + buffer_index,
+ input,
+ buffer_space);
+ transform(buffer);
- buffer_index = 0; // so we can buffer remaining
- }
- else
- input_index=0; // so we can buffer the whole input
+ for (input_index = buffer_space; input_index + 63 < input_length; input_index += 64)
+ transform(input + input_index);
+ buffer_index = 0; // so we can buffer remaining
+ }
+ else
+ input_index = 0; // so we can buffer the whole input
- // and here we do the buffering:
- memcpy(buffer+buffer_index, input+input_index, input_length-input_index); /* Flawfinder: ignore */
+ // and here we do the buffering:
+ memcpy(buffer + buffer_index, input + input_index, input_length - input_index); /* Flawfinder: ignore */
}
-
-
// MD5 update for files.
// Like above, except that it works on files (and uses above as a primitive.)
+void LLMD5::update(FILE* file)
+{
+ unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
+ int len;
-void LLMD5::update(FILE* file){
-
- unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
- int len;
-
- while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) )
- update(buffer, len);
-
- fclose (file);
+ while ((len = (int)fread(buffer, 1, BLOCK_LEN, file)))
+ update(buffer, len);
+ fclose(file);
}
// MD5 update for istreams.
// Like update for files; see above.
+void LLMD5::update(std::istream& stream)
+{
+ unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
+ int len;
-void LLMD5::update(std::istream& stream){
-
- unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
- int len;
-
- while (stream.good()){
- stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable.
- len=(int)stream.gcount();
- update(buffer, len);
- }
-
+ while (stream.good())
+ {
+ stream.read((char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable.
+ len = (int)stream.gcount();
+ update(buffer, len);
+ }
}
-void LLMD5::update(const std::string& s)
+void LLMD5::update(const std::string& s)
{
- update((unsigned char *)s.c_str(),s.length());
+ update((unsigned char*)s.c_str(), s.length());
}
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
-
-
-void LLMD5::finalize (){
-
- unsigned char bits[8]; /* Flawfinder: ignore */
- size_t index, padLen;
- static uint8_t PADDING[64]={
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+void LLMD5::finalize()
+{
+ unsigned char bits[8]; /* Flawfinder: ignore */
+ size_t index, padLen;
+ static uint8_t PADDING[64] =
+ {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- if (finalized){
- std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl;
- return;
- }
-
- // Save number of bits.
- // Treat count, a uint64_t, as uint32_t[2].
- encode (bits, reinterpret_cast<uint32_t*>(&count), 8);
+ if (finalized)
+ {
+ std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl;
+ return;
+ }
- // Pad out to 56 mod 64.
- index = size_t((count >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- update (PADDING, padLen);
+ // Save number of bits.
+ // Treat count, a uint64_t, as uint32_t[2].
+ encode(bits, reinterpret_cast<uint32_t*>(&count), 8);
- // Append length (before padding)
- update (bits, 8);
+ // Pad out to 56 mod 64.
+ index = size_t((count >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ update(PADDING, padLen);
- // Store state in digest
- encode (digest, state, 16);
+ // Append length (before padding)
+ update(bits, 8);
- // Zeroize sensitive information
- memset (buffer, 0, sizeof(*buffer));
+ // Store state in digest
+ encode(digest, state, 16);
- finalized=1;
+ // Zeroize sensitive information
+ memset(buffer, 0, sizeof(buffer));
+ finalized = true;
}
-
-
-
-LLMD5::LLMD5(FILE *file){
-
- init(); // must be called be all constructors
- update(file);
- finalize ();
+LLMD5::LLMD5(FILE* file)
+{
+ init(); // must be called be all constructors
+ update(file);
+ finalize();
}
-
-
-
-LLMD5::LLMD5(std::istream& stream){
-
- init(); // must called by all constructors
- update (stream);
- finalize();
+LLMD5::LLMD5(std::istream& stream)
+{
+ init(); // must called by all constructors
+ update(stream);
+ finalize();
}
// Digest a string of the format ("%s:%i" % (s, number))
-LLMD5::LLMD5(const unsigned char *string, const unsigned int number)
+LLMD5::LLMD5(const unsigned char* string, const unsigned int number)
{
- const char *colon = ":";
- char tbuf[16]; /* Flawfinder: ignore */
+ const char* colon = ":";
+ char tbuf[16]; /* Flawfinder: ignore */
init();
- update(string, (U32)strlen((const char *) string)); /* Flawfinder: ignore */
- update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */
- snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */
- update((const unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */
+ update(string, (U32)strlen((const char*)string)); /* Flawfinder: ignore */
+ update((const unsigned char*)colon, (U32)strlen(colon)); /* Flawfinder: ignore */
+ snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */
+ update((const unsigned char*)tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */
finalize();
}
// Digest a string
-LLMD5::LLMD5(const unsigned char *s)
+LLMD5::LLMD5(const unsigned char* s)
{
init();
- update(s, (U32)strlen((const char *) s)); /* Flawfinder: ignore */
+ update(s, (U32)strlen((const char*)s)); /* Flawfinder: ignore */
finalize();
}
-void LLMD5::raw_digest(unsigned char *s) const
+void LLMD5::raw_digest(unsigned char* s) const
{
if (!finalized)
{
- std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "<<
- "finalized the digest!" << std::endl;
+ std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "
+ << "finalized the digest!" << std::endl;
s[0] = '\0';
return;
}
- memcpy(s, digest, 16); /* Flawfinder: ignore */
- return;
+ memcpy(s, digest, 16); /* Flawfinder: ignore */
}
-
-
-void LLMD5::hex_digest(char *s) const
+void LLMD5::hex_digest(char* s) const
{
- int i;
-
if (!finalized)
{
- std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "<<
- "finalized the digest!" <<std::endl;
+ std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "
+ << "finalized the digest!" << std::endl;
s[0] = '\0';
return;
}
- for (i=0; i<16; i++)
+ for (int i = 0; i < 16; i++)
{
- sprintf(s+i*2, "%02x", digest[i]); /* Flawfinder: ignore */
+ sprintf(s + i * 2, "%02x", digest[i]); /* Flawfinder: ignore */
}
- s[32]='\0';
-
- return;
+ s[32] = '\0';
}
-
-
-
-
-
-std::ostream& operator<<(std::ostream &stream, LLMD5 context)
+std::ostream& operator<<(std::ostream& stream, const LLMD5& context)
{
char s[33]; /* Flawfinder: ignore */
context.hex_digest(s);
@@ -320,7 +287,7 @@ bool operator==(const LLMD5& a, const LLMD5& b)
unsigned char b_guts[16];
a.raw_digest(a_guts);
b.raw_digest(b_guts);
- if (memcmp(a_guts,b_guts,16)==0)
+ if (memcmp(a_guts, b_guts, 16) == 0)
return true;
else
return false;
@@ -328,30 +295,27 @@ bool operator==(const LLMD5& a, const LLMD5& b)
bool operator!=(const LLMD5& a, const LLMD5& b)
{
- return !(a==b);
+ return !(a == b);
}
// PRIVATE METHODS:
+void LLMD5::init()
+{
+ finalized = false; // we just started!
-void LLMD5::init(){
- finalized=0; // we just started!
-
- // Nothing counted, so count=0
- count = 0;
+ // Nothing counted, so count=0
+ count = 0;
- // Load magic initialization constants.
- state[0] = 0x67452301;
- state[1] = 0xefcdab89;
- state[2] = 0x98badcfe;
- state[3] = 0x10325476;
+ // Load magic initialization constants.
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
}
-
-
// Constants for MD5Transform routine.
// Although we could use C++ style constants, defines are actually better,
// since they let us easily evade scope clashes.
-
#define S11 7
#define S12 12
#define S13 17
@@ -381,153 +345,144 @@ void LLMD5::init(){
/* ROTATE_LEFT rotates x left n bits.
*/
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (U32)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (U32)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (U32)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (U32)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-
+#define FF(a, b, c, d, x, s, ac) \
+ { \
+ (a) += F((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) \
+ { \
+ (a) += G((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) \
+ { \
+ (a) += H((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) \
+ { \
+ (a) += I((b), (c), (d)) + (x) + (U32)(ac); \
+ (a) = ROTATE_LEFT((a), (s)); \
+ (a) += (b); \
+ }
// LLMD5 basic transformation. Transforms state based on block.
-void LLMD5::transform (const U8 block[64]){
-
- uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- decode (x, block, 64);
-
- assert(!finalized); // not just a user error, since the method is private
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- // Zeroize sensitive information.
- memset ( (uint8_t *) x, 0, sizeof(x));
-
+void LLMD5::transform(const U8 block[64])
+{
+ uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ decode(x, block, 64);
+
+ assert(!finalized); // not just a user error, since the method is private
+
+ /* Round 1 */
+ FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
+ FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
+ FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
+ FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
+ FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
+ FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
+ FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
+ FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
+ FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
+ FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
+ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
+ GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
+ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
+ GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
+ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
+ GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
+ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
+ GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
+ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
+ GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
+ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
+ HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
+ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
+ HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
+ HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
+ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
+ HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
+ HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
+ HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
+ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
+ II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
+ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
+ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
+ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
+ II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
+ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
+ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
+ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
+ II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ // Zeroize sensitive information.
+ memset(x, 0, sizeof(x));
}
-
-
// Encodes input (uint32_t) into output (unsigned char). Assumes len is
// a multiple of 4.
-void LLMD5::encode (uint8_t *output, const uint32_t *input, const size_t len) {
-
- size_t i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (uint8_t) (input[i] & 0xff);
- output[j+1] = (uint8_t) ((input[i] >> 8) & 0xff);
- output[j+2] = (uint8_t) ((input[i] >> 16) & 0xff);
- output[j+3] = (uint8_t) ((input[i] >> 24) & 0xff);
- }
+void LLMD5::encode(uint8_t* output, const uint32_t* input, const size_t len)
+{
+ for (size_t i = 0, j = 0; j < len; i++, j += 4)
+ {
+ output[j] = (uint8_t)(input[i] & 0xff);
+ output[j + 1] = (uint8_t)((input[i] >> 8) & 0xff);
+ output[j + 2] = (uint8_t)((input[i] >> 16) & 0xff);
+ output[j + 3] = (uint8_t)((input[i] >> 24) & 0xff);
+ }
}
-
-
-
// Decodes input (unsigned char) into output (uint32_t). Assumes len is
// a multiple of 4.
-void LLMD5::decode (uint32_t *output, const uint8_t *input, const size_t len){
-
- size_t i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
- (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
+void LLMD5::decode(uint32_t* output, const uint8_t* input, const size_t len)
+{
+ for (size_t i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
+ (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
}
-
-
diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h
index 46c79cf5a2..ad063fda46 100644
--- a/indra/llcommon/llmd5.h
+++ b/indra/llcommon/llmd5.h
@@ -67,59 +67,57 @@ documentation and/or software.
*/
-#include <cstdint> // uint32_t et al.
+#include <cstdint> // uint32_t et al.
// use for the raw digest output
const int MD5RAW_BYTES = 16;
// use for outputting hex digests
-const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null
+const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null
const int MD5HEX_STR_BYTES = 32; // message system fixed size
-class LL_COMMON_API LLMD5 {
-// how many bytes to grab at a time when checking files
- static const int BLOCK_LEN;
+class LL_COMMON_API LLMD5
+{
+ // how many bytes to grab at a time when checking files
+ static const int BLOCK_LEN;
public:
-// methods for controlled operation:
- LLMD5 (); // simple initializer
- void update (const uint8_t *input, const size_t input_length);
- void update (std::istream& stream);
- void update (FILE *file);
- void update (const std::string& str);
- void finalize ();
-
-// constructors for special circumstances. All these constructors finalize
-// the MD5 context.
- LLMD5 (const unsigned char *string); // digest string, finalize
- LLMD5 (std::istream& stream); // digest stream, finalize
- LLMD5 (FILE *file); // digest file, close, finalize
- LLMD5 (const unsigned char *string, const unsigned int number);
-
-// methods to acquire finalized result
- void raw_digest(unsigned char *array) const; // provide 16-byte array for binary data
- void hex_digest(char *string) const; // provide 33-byte array for ascii-hex string
-
- friend LL_COMMON_API std::ostream& operator<< (std::ostream&, LLMD5 context);
+ // methods for controlled operation:
+ LLMD5(); // simple initializer
+ void update(const uint8_t* input, const size_t input_length);
+ void update(std::istream& stream);
+ void update(FILE* file);
+ void update(const std::string& str);
+ void finalize();
+
+ // constructors for special circumstances. All these constructors finalize
+ // the MD5 context.
+ LLMD5(const unsigned char* string); // digest string, finalize
+ LLMD5(std::istream& stream); // digest stream, finalize
+ LLMD5(FILE* file); // digest file, close, finalize
+ LLMD5(const unsigned char* string, const unsigned int number);
+
+ // methods to acquire finalized result
+ void raw_digest(unsigned char* array) const; // provide 16-byte array for binary data
+ void hex_digest(char* string) const; // provide 33-byte array for ascii-hex string
+
+ friend LL_COMMON_API std::ostream& operator<<(std::ostream&, const LLMD5& context);
private:
-
-
-// next, the private data:
- uint32_t state[4];
- uint64_t count; // number of *bits*, mod 2^64
- uint8_t buffer[64]; // input buffer
- uint8_t digest[16];
- uint8_t finalized;
-
-// last, the private methods, mostly static:
- void init (); // called by all constructors
- void transform (const uint8_t *buffer); // does the real update work. Note
- // that length is implied to be 64.
-
- static void encode (uint8_t *dest, const uint32_t *src, const size_t length);
- static void decode (uint32_t *dest, const uint8_t *src, const size_t length);
-
+ // next, the private data:
+ uint32_t state[4];
+ uint64_t count; // number of *bits*, mod 2^64
+ uint8_t buffer[64]; // input buffer
+ uint8_t digest[16];
+ bool finalized;
+
+ // last, the private methods, mostly static:
+ void init(); // called by all constructors
+ void transform(const uint8_t* buffer); // does the real update work. Note
+ // that length is implied to be 64.
+
+ static void encode(uint8_t* dest, const uint32_t* src, const size_t length);
+ static void decode(uint32_t* dest, const uint8_t* src, const size_t length);
};
LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b);
diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp
index 96ec94fe0f..392f235aad 100644
--- a/indra/llrender/llfontvertexbuffer.cpp
+++ b/indra/llrender/llfontvertexbuffer.cpp
@@ -42,6 +42,8 @@ LLFontVertexBuffer::~LLFontVertexBuffer()
void LLFontVertexBuffer::reset()
{
+ // Todo: some form of debug only frequecy check&assert to see if this is happening too often.
+ // Regenerating this list is expensive
mBufferList.clear();
}
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 60b6115b34..66b274c33f 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -436,6 +436,9 @@ void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit
{
mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
}
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
if (all_selected)
{
@@ -617,6 +620,10 @@ void LLLineEditor::replaceWithSuggestion(U32 index)
mText.insert(it->first, suggestion);
setCursor(it->first + (S32)suggestion.length());
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+
break;
}
}
@@ -969,6 +976,10 @@ void LLLineEditor::removeChar()
mText.erase(getCursor() - 1, 1);
setCursor(getCursor() - 1);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
else
{
@@ -992,6 +1003,10 @@ void LLLineEditor::addChar(const llwchar uni_char)
return;
mText.erase(getCursor(), 1);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
S32 cur_bytes = static_cast<S32>(mText.getString().size());
@@ -1022,6 +1037,10 @@ void LLLineEditor::addChar(const llwchar uni_char)
mText.insert(getCursor(), w_buf);
setCursor(getCursor() + 1);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
else
{
@@ -1186,6 +1205,10 @@ void LLLineEditor::deleteSelection()
mText.erase(left_pos, selection_length);
deselect();
setCursor(left_pos);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
}
@@ -1346,6 +1369,10 @@ void LLLineEditor::pasteHelper(bool is_primary)
setCursor( getCursor() + (S32)clean_string.length() );
deselect();
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+
// Validate new string and rollback the if needed.
bool need_to_rollback = mPrevalidator && !mPrevalidator.validate(mText.getWString());
if (need_to_rollback)
@@ -1506,6 +1533,10 @@ bool LLLineEditor::handleSpecialKey(KEY key, MASK mask)
{
mText.assign(*(--mCurrentHistoryLine));
setCursorToEnd();
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
else
{
@@ -1523,6 +1554,10 @@ bool LLLineEditor::handleSpecialKey(KEY key, MASK mask)
{
mText.assign( *(++mCurrentHistoryLine) );
setCursorToEnd();
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
}
else
{
@@ -1897,7 +1932,8 @@ void LLLineEditor::draw()
if( select_left > mScrollHPos )
{
// unselected, left side
- rendered_text = mGLFont->render(
+ rendered_text = mFontBufferPreSelection.render(
+ mGLFont,
mText, mScrollHPos,
rendered_pixels_right, text_bottom,
text_color,
@@ -1919,7 +1955,8 @@ void LLLineEditor::draw()
gl_rect_2d(ll_round(rendered_pixels_right), cursor_top, ll_round(rendered_pixels_right)+width, cursor_bottom, color);
LLColor4 tmp_color( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], alpha );
- rendered_text += mGLFont->render(
+ rendered_text += mFontBufferSelection.render(
+ mGLFont,
mText, mScrollHPos + rendered_text,
rendered_pixels_right, text_bottom,
tmp_color,
@@ -1934,7 +1971,8 @@ void LLLineEditor::draw()
if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
// unselected, right side
- rendered_text += mGLFont->render(
+ rendered_text += mFontBufferPostSelection.render(
+ mGLFont,
mText, mScrollHPos + rendered_text,
rendered_pixels_right, text_bottom,
text_color,
@@ -1948,7 +1986,8 @@ void LLLineEditor::draw()
}
else
{
- rendered_text = mGLFont->render(
+ rendered_text = mFontBufferPreSelection.render(
+ mGLFont,
mText, mScrollHPos,
rendered_pixels_right, text_bottom,
text_color,
@@ -2108,7 +2147,8 @@ void LLLineEditor::draw()
//to give indication that it is not text you typed in
if (0 == mText.length() && (mReadOnly || mShowLabelFocused))
{
- mGLFont->render(mLabel.getWString(), 0,
+ mFontBufferLabel.render(mGLFont,
+ mLabel.getWString(), 0,
(F32)mTextLeftEdge, (F32)text_bottom,
label_color,
LLFontGL::LEFT,
@@ -2133,7 +2173,8 @@ void LLLineEditor::draw()
// draw label if no text provided
if (0 == mText.length())
{
- mGLFont->render(mLabel.getWString(), 0,
+ mFontBufferLabel.render(mGLFont,
+ mLabel.getWString(), 0,
(F32)mTextLeftEdge, (F32)text_bottom,
label_color,
LLFontGL::LEFT,
@@ -2404,12 +2445,16 @@ void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
bool LLLineEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
{
mText.setArg(key, text);
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
return true;
}
bool LLLineEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
{
mLabel.setArg(key, text);
+ mFontBufferLabel.reset();
return true;
}
@@ -2508,6 +2553,9 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
mPreeditOverwrittenWString.clear();
}
mText.insert(insert_preedit_at, mPreeditWString);
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
mPreeditStandouts = preedit_standouts;
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index cdd22413e7..12fe800acb 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -40,6 +40,7 @@
#include "llframetimer.h"
#include "lleditmenuhandler.h"
+#include "llfontvertexbuffer.h"
#include "llspellcheckmenuhandler.h"
#include "lluictrl.h"
#include "lluiimage.h"
@@ -344,6 +345,10 @@ protected:
LLViewBorder* mBorder;
const LLFontGL* mGLFont;
+ LLFontVertexBuffer mFontBufferPreSelection;
+ LLFontVertexBuffer mFontBufferSelection;
+ LLFontVertexBuffer mFontBufferPostSelection;
+ LLFontVertexBuffer mFontBufferLabel;
S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes
S32 mMaxLengthChars; // Maximum number of characters in the string
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0aebf7543c..615619d244 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -948,7 +948,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
{
-
beforeValueChange();
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
while(seg_iter != mSegments.end())
@@ -1325,6 +1324,7 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent)
//virtual
void LLTextBase::draw()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
// reflow if needed, on demand
reflow();
@@ -2586,6 +2586,11 @@ const LLWString& LLTextBase::getWText() const
return getViewModel()->getDisplay();
}
+S32 LLTextBase::getTextGeneration() const
+{
+ return getViewModel()->getDisplayGeneration();
+}
+
// If round is true, if the position is on the right half of a character, the cursor
// will be put to its right. If round is false, the cursor will always be put to the
// character's left.
@@ -3280,7 +3285,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
: LLTextSegment(start, end),
mStyle( style ),
mToken(NULL),
- mEditor(editor)
+ mEditor(editor),
+ mLastGeneration(-1)
{
mFontHeight = mStyle->getFont()->getLineHeight();
@@ -3294,7 +3300,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
LLNormalTextSegment::LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible)
: LLTextSegment(start, end),
mToken(NULL),
- mEditor(editor)
+ mEditor(editor),
+ mLastGeneration(-1)
{
mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
@@ -3313,25 +3320,42 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
{
return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect);
}
+ else
+ {
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+ }
return draw_rect.mLeft;
}
// Draws a single text segment, reversing the color for selection if needed.
F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect)
{
- F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
-
- const LLWString &text = getWText();
-
F32 right_x = rect.mLeft;
if (!mStyle->isVisible())
{
return right_x;
}
+ F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
+
+ const LLWString& text = getWText();
+ S32 text_gen = mEditor.getTextGeneration();
+ bool is_text_read_only = mEditor.getReadOnly();
+
+ if (text_gen != mLastGeneration)
+ {
+ mLastGeneration = text_gen;
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+ }
+
const LLFontGL* font = mStyle->getFont();
- LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % (alpha * mStyle->getAlpha());
+ LLColor4 color = (is_text_read_only ? mStyle->getReadOnlyColor() : mStyle->getColor()) % (alpha * mStyle->getAlpha());
if( selection_start > seg_start )
{
@@ -3339,16 +3363,40 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 start = seg_start;
S32 end = llmin( selection_start, seg_end );
S32 length = end - start;
- font->render(text, start,
- rect,
- color,
- LLFontGL::LEFT, mEditor.mTextVAlign,
- LLFontGL::NORMAL,
- mStyle->getShadowType(),
- length,
- &right_x,
- mEditor.getUseEllipses(),
- mEditor.getUseColor());
+ if (is_text_read_only)
+ {
+ mFontBufferPreSelection.render(
+ font,
+ text, start,
+ rect,
+ color,
+ LLFontGL::LEFT, mEditor.mTextVAlign,
+ LLFontGL::NORMAL,
+ mStyle->getShadowType(),
+ length,
+ &right_x,
+ mEditor.getUseEllipses(),
+ mEditor.getUseColor());
+ }
+ else
+ {
+ // Font buffer doesn't do well with changes and huge notecard with a bunch
+ // of segments will see a lot of buffer updates, so instead use derect
+ // rendering to cache.
+ // Todo: instead of mLastGeneration make buffer invalidation more fine grained
+ // like string hash of a given segment.
+ font->render(
+ text, start,
+ rect,
+ color,
+ LLFontGL::LEFT, mEditor.mTextVAlign,
+ LLFontGL::NORMAL,
+ mStyle->getShadowType(),
+ length,
+ &right_x,
+ mEditor.getUseEllipses(),
+ mEditor.getUseColor());
+ }
}
rect.mLeft = right_x;
@@ -3359,16 +3407,35 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 end = llmin( selection_end, seg_end );
S32 length = end - start;
- font->render(text, start,
- rect,
- mStyle->getSelectedColor().get(),
- LLFontGL::LEFT, mEditor.mTextVAlign,
- LLFontGL::NORMAL,
- LLFontGL::NO_SHADOW,
- length,
- &right_x,
- mEditor.getUseEllipses(),
- mEditor.getUseColor());
+ if (is_text_read_only)
+ {
+ mFontBufferSelection.render(
+ font,
+ text, start,
+ rect,
+ mStyle->getSelectedColor().get(),
+ LLFontGL::LEFT, mEditor.mTextVAlign,
+ LLFontGL::NORMAL,
+ LLFontGL::NO_SHADOW,
+ length,
+ &right_x,
+ mEditor.getUseEllipses(),
+ mEditor.getUseColor());
+ }
+ else
+ {
+ font->render(
+ text, start,
+ rect,
+ mStyle->getSelectedColor().get(),
+ LLFontGL::LEFT, mEditor.mTextVAlign,
+ LLFontGL::NORMAL,
+ LLFontGL::NO_SHADOW,
+ length,
+ &right_x,
+ mEditor.getUseEllipses(),
+ mEditor.getUseColor());
+ }
}
rect.mLeft = right_x;
if( selection_end < seg_end )
@@ -3377,16 +3444,36 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 start = llmax( selection_end, seg_start );
S32 end = seg_end;
S32 length = end - start;
- font->render(text, start,
- rect,
- color,
- LLFontGL::LEFT, mEditor.mTextVAlign,
- LLFontGL::NORMAL,
- mStyle->getShadowType(),
- length,
- &right_x,
- mEditor.getUseEllipses(),
- mEditor.getUseColor());
+ if (is_text_read_only)
+ {
+ mFontBufferPostSelection.render(
+ font,
+ text, start,
+ rect,
+ color,
+ LLFontGL::LEFT, mEditor.mTextVAlign,
+ LLFontGL::NORMAL,
+ mStyle->getShadowType(),
+ length,
+ &right_x,
+ mEditor.getUseEllipses(),
+ mEditor.getUseColor());
+ }
+ else
+ {
+ font->render(
+ text, start,
+ rect,
+ color,
+ LLFontGL::LEFT, mEditor.mTextVAlign,
+ LLFontGL::NORMAL,
+ mStyle->getShadowType(),
+ length,
+ &right_x,
+ mEditor.getUseEllipses(),
+ mEditor.getUseColor());
+
+ }
}
return right_x;
}
@@ -3573,6 +3660,15 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
return num_chars;
}
+void LLNormalTextSegment::updateLayout(const class LLTextBase& editor)
+{
+ LLTextSegment::updateLayout(editor);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+}
+
void LLNormalTextSegment::dump() const
{
LL_INFOS() << "Segment [" <<
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 00cf66b134..e2981c2637 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -30,6 +30,7 @@
#include "v4color.h"
#include "lleditmenuhandler.h"
+#include "llfontvertexbuffer.h"
#include "llspellcheckmenuhandler.h"
#include "llstyle.h"
#include "llkeywords.h"
@@ -131,6 +132,7 @@ public:
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
+ /*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
/*virtual*/ bool canEdit() const { return true; }
/*virtual*/ const LLUIColor& getColor() const { return mStyle->getColor(); }
@@ -161,6 +163,12 @@ protected:
LLKeywordToken* mToken;
std::string mTooltip;
boost::signals2::connection mImageLoadedConnection;
+
+ // font rendering
+ LLFontVertexBuffer mFontBufferPreSelection;
+ LLFontVertexBuffer mFontBufferSelection;
+ LLFontVertexBuffer mFontBufferPostSelection;
+ S32 mLastGeneration = -1;
};
// This text segment is the same as LLNormalTextSegment, the only difference
@@ -432,6 +440,7 @@ public:
// wide-char versions
void setWText(const LLWString& text);
const LLWString& getWText() const;
+ S32 getTextGeneration() const;
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index 93106b344f..35963c2b99 100644
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
@@ -82,11 +82,20 @@ void LLTextViewModel::setValue(const LLSD& value)
// approximate LLSD storage usage
LLViewModel::setValue(value);
mDisplay = utf8str_to_wstring(mStringValue = value.asString());
+ mDisplayGeneration++;
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
+LLWString& LLTextViewModel::getEditableDisplay()
+{
+ mDirty = true;
+ mDisplayGeneration++;
+ mUpdateFromDisplay = true;
+ return mDisplay;
+}
+
void LLTextViewModel::setDisplay(const LLWString& value)
{
// This is the strange way to alter the value. Normally we'd setValue()
@@ -94,6 +103,7 @@ void LLTextViewModel::setDisplay(const LLWString& value)
// value. But a text editor might want to edit the display string
// directly, then convert back to UTF8 on commit.
mDisplay = value;
+ mDisplayGeneration++;
mDirty = true;
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
// more setDisplay() calls than getValue() calls. Just flag that it needs
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 6cf2200a81..16b0800ce2 100644
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -105,7 +105,8 @@ public:
// New functions
/// Get the stored value in string form
const LLWString& getDisplay() const { return mDisplay; }
- LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; }
+ S32 getDisplayGeneration() const { return mDisplayGeneration; }
+ LLWString& getEditableDisplay();
/**
* Set the display string directly (see LLTextEditor). What the user is
@@ -120,6 +121,7 @@ private:
/// To avoid converting every widget's stored value from LLSD to LLWString
/// every frame, cache the converted value
LLWString mDisplay;
+ S32 mDisplayGeneration = -1;
/// As the user edits individual characters (setDisplay()), defer
/// LLWString-to-UTF8 conversions until s/he's done.
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 2466ee5973..0c068ff993 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -963,59 +963,87 @@ void LLPanelMainInventory::draw()
void LLPanelMainInventory::updateItemcountText()
{
- if(mItemCount != gInventory.getItemCount())
- {
- mItemCount = gInventory.getItemCount();
- mItemCountString = "";
- LLLocale locale(LLLocale::USER_LOCALE);
- LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
- }
-
- if(mCategoryCount != gInventory.getCategoryCount())
+ bool update = false;
+ if (mSingleFolderMode)
{
- mCategoryCount = gInventory.getCategoryCount();
- mCategoryCountString = "";
- LLLocale locale(LLLocale::USER_LOCALE);
- LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
- }
-
- LLStringUtil::format_map_t string_args;
- string_args["[ITEM_COUNT]"] = mItemCountString;
- string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
- string_args["[FILTER]"] = getFilterText();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
- std::string text = "";
+ gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items);
+ S32 item_count = items ? (S32)items->size() : 0;
+ S32 cat_count = cats ? (S32)cats->size() : 0;
- if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
- {
- text = getString("ItemcountFetching", string_args);
+ if (mItemCount != item_count)
+ {
+ mItemCount = item_count;
+ update = true;
+ }
+ if (mCategoryCount != cat_count)
+ {
+ mCategoryCount = cat_count;
+ update = true;
+ }
}
- else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ else
{
- text = getString("ItemcountCompleted", string_args);
+ if (mItemCount != gInventory.getItemCount())
+ {
+ mItemCount = gInventory.getItemCount();
+ update = true;
+ }
+
+ if (mCategoryCount != gInventory.getCategoryCount())
+ {
+ mCategoryCount = gInventory.getCategoryCount();
+ update = true;
+ }
}
- else
+
+ if (mLastFilterText != getFilterText())
{
- text = getString("ItemcountUnknown", string_args);
+ mLastFilterText = getFilterText();
+ update = true;
}
- if (mSingleFolderMode)
+ if (update)
{
- LLInventoryModel::cat_array_t *cats;
- LLInventoryModel::item_array_t *items;
+ mItemCountString = "";
+ LLLocale locale(LLLocale::USER_LOCALE);
+ LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
- gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items);
+ mCategoryCountString = "";
+ LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
- if (items && cats)
+ LLStringUtil::format_map_t string_args;
+ string_args["[ITEM_COUNT]"] = mItemCountString;
+ string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
+ string_args["[FILTER]"] = mLastFilterText;
+
+ std::string text = "";
+
+ if (mSingleFolderMode)
{
- string_args["[ITEM_COUNT]"] = llformat("%d", items->size());
- string_args["[CATEGORY_COUNT]"] = llformat("%d", cats->size());
text = getString("ItemcountCompleted", string_args);
}
- }
+ else
+ {
+ if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
+ {
+ text = getString("ItemcountFetching", string_args);
+ }
+ else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ {
+ text = getString("ItemcountCompleted", string_args);
+ }
+ else
+ {
+ text = getString("ItemcountUnknown", string_args);
+ }
+ }
- mCounterCtrl->setValue(text);
- mCounterCtrl->setToolTip(text);
+ mCounterCtrl->setValue(text);
+ mCounterCtrl->setToolTip(text);
+ }
}
void LLPanelMainInventory::onFocusReceived()
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 3347ab904b..d28daddd73 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -196,9 +196,10 @@ private:
LLSaveFolderState* mSavedFolderState;
std::string mFilterText;
std::string mFilterSubString;
- S32 mItemCount;
+ S32 mItemCount = 0;
+ std::string mLastFilterText;
std::string mItemCountString;
- S32 mCategoryCount;
+ S32 mCategoryCount = 0;
std::string mCategoryCountString;
LLComboBox* mSearchTypeCombo;
diff --git a/indra/newview/skins/default/textures/map_avatar_you_32.tga b/indra/newview/skins/default/textures/map_avatar_you_32.tga
index 782207efd6..84b57aceaf 100644
--- a/indra/newview/skins/default/textures/map_avatar_you_32.tga
+++ b/indra/newview/skins/default/textures/map_avatar_you_32.tga
Binary files differ