/* * Quixadhal - I rewrote this too, so that it uses colorcode. It may not * be as efficient as just walking over the string and counting, but it * keeps us from duplicating the code several times. * * This function returns the intended screen length of a string which has * color codes embedded in it. It does this by stripping the codes out * entirely (A NULL descriptor means ANSI will be FALSE). */ int color_strlen( const char *src ) { register unsigned int i = 0; int len = 0; if( !src || !*src ) /* Move along, nothing to see here */ return 0; for( i = 0; i < strlen( src ); ) { char dst[20]; int vislen; switch ( src[i] ) { case '&': /* NORMAL, Foreground colour */ case '^': /* BACKGROUND colour */ case '}': /* BLINK Foreground colour */ *dst = '\0'; vislen = 0; i += colorcode( &src[i], dst, NULL, 20, &vislen ); /* Skip input token */ len += vislen; /* Count output token length */ break; /* this was missing - if you have issues, remove it */ default: /* No conversion, just count */ ++len; ++i; break; } } return len; }
/* * Quixadhal - This takes a string and converts any and all color tokens * in it to the desired output tokens, using the provided character's * preferences. */ char *colorize( const char *txt, DESCRIPTOR_DATA * d ) { static char result[MAX_STRING_LENGTH]; *result = '\0'; if( txt && *txt && d ) { const char *colstr; const char *prevstr = txt; char colbuf[20]; int ln; while( ( colstr = strpbrk( prevstr, "&^}hH" ) ) != NULL ) { register int reslen = 0; if( colstr > prevstr ) { if( ( MAX_STRING_LENGTH - ( reslen = strlen( result ) ) ) <= ( colstr - prevstr ) ) { bug( "%s: OVERFLOW in internal MAX_STRING_LENGTH buffer!", __PRETTY_FUNCTION__ ); break; } strncat( result, prevstr, ( colstr - prevstr ) ); /* Leave this one alone! BAD THINGS(TM) will happen if you don't! */ result[reslen + ( colstr - prevstr )] = '\0'; /* strncat will NOT NULL terminate this! */ } if( colstr[0] == 'h' || colstr[0] == 'H' ) if( colstr[1] == 't' || colstr[1] == 'T' ) if( colstr[2] == 't' || colstr[2] == 'T' ) if( colstr[3] == 'p' || colstr[3] == 'P' ) { char http[MAX_INPUT_LENGTH]; one_argument( colstr, http ); mudstrlcat( result, http, sizeof( result ) ); ln = strlen( http ); prevstr = colstr + ln; continue; } ln = colorcode( colstr, colbuf, d, 20, NULL ); if( ln > 0 ) { mudstrlcat( result, colbuf, MAX_STRING_LENGTH ); prevstr = colstr + ln; } else prevstr = colstr + 1; } if( *prevstr ) mudstrlcat( result, prevstr, MAX_STRING_LENGTH ); } return result; }
/* * Quixadhal - This takes a string and converts any and all color tokens * in it to the desired output tokens, using the provided character's * preferences. */ const char *colorize( const string & txt, descriptor_data * d ) { static char result[MSL]; *result = '\0'; if( !txt.empty( ) && d ) { const char *colstr; const char *prevstr = txt.c_str( ); char colbuf[20]; int ln; while( ( colstr = strpbrk( prevstr, "&{}hH" ) ) != nullptr ) { register int reslen = 0; if( colstr > prevstr ) { if( ( MSL - ( reslen = strlen( result ) ) ) <= ( colstr - prevstr ) ) { bug( "%s: OVERFLOW in internal MSL buffer!", __PRETTY_FUNCTION__ ); break; } strncat( result, prevstr, ( colstr - prevstr ) ); /* Leave this one alone! BAD THINGS(TM) will happen if you don't! */ result[reslen + ( colstr - prevstr )] = '\0'; /* strncat will NOT nullptr terminate this! */ } ln = colorcode( colstr, colbuf, d, 20, nullptr ); if( colstr[0] == 'h' || colstr[0] == 'H' ) if( colstr[1] == 't' || colstr[1] == 'T' ) if( colstr[2] == 't' || colstr[2] == 'T' ) if( colstr[3] == 'p' || colstr[3] == 'P' ) { char http[MIL]; one_argument( colstr, http ); mudstrlcat( result, http, sizeof( result ) ); ln = strlen( http ); prevstr = colstr + ln; continue; } if( ln > 0 ) { mudstrlcat( result, colbuf, MSL ); prevstr = colstr + ln; } else prevstr = colstr + 1; } if( *prevstr ) mudstrlcat( result, prevstr, MSL ); } return result; }
int get_line( char *desc, size_t max_len ) { size_t i, j = 0; /* * Return if it's short enough for one line */ if ( strlen( desc ) <= max_len ) return 0; /* * Calculate end point in string without color */ for ( i = 0; i <= strlen( desc ); ++i ) { char dst[20]; int vislen; switch ( desc[i] ) { case '&': /* NORMAL, Foreground colour */ case '^': /* BACKGROUND colour */ case '}': /* BLINK Foreground colour */ *dst = '\0'; vislen = 0; i += colorcode( &desc[i], dst, NULL, 20, &vislen ); /* Skip input token */ j += vislen; /* Count output token length */ break; /* this was missing - if you have issues, remove it */ default: /* No conversion, just count */ ++j; break; } if ( j > max_len ) break; } /* * End point is now in i, find the nearest space */ for ( j = i; j > 0; --j ) { if ( desc[j] == ' ' ) break; } /* * There could be a problem if there are no spaces on the line */ return j + 1; }
void CTextWrap::SplitTextInWords(const std::u8string& text, std::list<word>* words, std::list<colorcode>* colorcodes) { const unsigned int length = (unsigned int)text.length(); const float spaceAdvance = GetGlyph(spaceUTF16).advance; words->push_back(word()); word* w = &(words->back()); unsigned int numChar = 0; for (int pos = 0; pos < length; pos++) { const char8_t& c = text[pos]; switch(c) { // space case spaceUTF16: if (!w->isSpace) { if (!w->isLineBreak) { w->width = GetTextWidth(w->text); } words->push_back(word()); w = &(words->back()); w->isSpace = true; w->pos = numChar; } w->numSpaces++; w->width = spaceAdvance * w->numSpaces; break; // inlined colorcodes case ColorCodeIndicator: { colorcodes->push_back(colorcode()); colorcode& cc = colorcodes->back(); cc.pos = numChar; SkipColorCodes(text, &pos, &(cc.color)); if (pos<0) { pos = length; } else { // SkipColorCodes jumps 1 too far (it jumps on the first non // colorcode char, but our for-loop will still do "pos++;") pos--; } } break; case ColorResetIndicator: { colorcode* cc = &colorcodes->back(); if (cc->pos != numChar) { colorcodes->push_back(colorcode()); cc = &colorcodes->back(); cc->pos = numChar; } cc->resetColor = true; } break; // newlines case 0x0d: // CR+LF if (pos+1 < length && text[pos+1] == 0x0a) pos++; case 0x0a: // LF if (w->isSpace) { w->width = spaceAdvance * w->numSpaces; } else if (!w->isLineBreak) { w->width = GetTextWidth(w->text); } words->push_back(word()); w = &(words->back()); w->isLineBreak = true; w->pos = numChar; break; // printable chars default: if (w->isSpace || w->isLineBreak) { if (w->isSpace) { w->width = spaceAdvance * w->numSpaces; } else if (!w->isLineBreak) { w->width = GetTextWidth(w->text); } words->push_back(word()); w = &(words->back()); w->pos = numChar; } w->text += c; numChar++; } } if (w->isSpace) { w->width = spaceAdvance * w->numSpaces; } else if (!w->isLineBreak) { w->width = GetTextWidth(w->text); } }