diff options
| author | Wiimm <wiimm@wiimm.de> | 2022-05-13 19:22:13 +0200 |
|---|---|---|
| committer | Wiimm <wiimm@wiimm.de> | 2022-05-13 19:22:13 +0200 |
| commit | 568365f5bdd4dc71a156ca963d89ac002f405a34 (patch) | |
| tree | 730d0311536d8fd46a56b74e2c8cac028e778243 /project/dclib/dclib-utf8.c | |
| parent | 9ae8841ec4720e74173e2f72fac33f0848bbf435 (diff) | |
SZS v2.27a
Diffstat (limited to 'project/dclib/dclib-utf8.c')
| -rw-r--r-- | project/dclib/dclib-utf8.c | 288 |
1 files changed, 278 insertions, 10 deletions
diff --git a/project/dclib/dclib-utf8.c b/project/dclib/dclib-utf8.c index 29a7f81..1ad06ce 100644 --- a/project/dclib/dclib-utf8.c +++ b/project/dclib/dclib-utf8.c @@ -14,16 +14,16 @@ * * *************************************************************************** * * - * Copyright (c) 2012-2021 by Dirk Clemens <wiimm@wiimm.de> * + * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> * * * *************************************************************************** * * - * This program is free software; you can redistribute it and/or modify * + * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * This program is distributed in the hope that it will be useful, * + * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * @@ -108,7 +108,7 @@ int GetUTF8CharLength ( u32 code ) char * NextUTF8Char ( ccp ptr ) { - // go to next next UTF8 character + // goto next UTF8 character switch (CheckUTF8Mode(*ptr)) { @@ -144,7 +144,7 @@ char * NextUTF8Char ( ccp ptr ) char * NextUTF8CharE( ccp ptr, ccp end ) { - // go to next next UTF8 character + // goto next UTF8 character if ( ptr >= end ) return (char*)end; @@ -181,6 +181,20 @@ char * NextUTF8CharE( ccp ptr, ccp end ) /////////////////////////////////////////////////////////////////////////////// +char * NextEUTF8Char ( ccp ptr ) +{ + return NextUTF8Char(SkipEscapes(ptr)); +} + +//----------------------------------------------------------------------------- + +char * NextEUTF8CharE ( ccp ptr, ccp end ) +{ + return NextUTF8CharE(SkipEscapesE(ptr,end),end); +} + +/////////////////////////////////////////////////////////////////////////////// + char * PrevUTF8Char ( ccp str ) { // go to the previous UTC character @@ -265,6 +279,82 @@ char * PrevUTF8CharB ( ccp str, ccp begin ) /////////////////////////////////////////////////////////////////////////////// +char * SkipUTF8Char ( ccp str, int skip ) +{ + if (str) + { + if ( skip < 0 ) + skip += ScanUTF8Length(str); + while ( skip-- > 0 ) + { + ccp next = NextUTF8Char(str); + if ( str == next ) + break; + str = next; + } + } + return (char*)str; +} + +//----------------------------------------------------------------------------- + +char * SkipUTF8CharE ( ccp str, ccp end, int skip ) +{ + if (str) + { + if ( skip < 0 ) + skip += ScanUTF8LengthE(str,end); + while ( skip-- > 0 ) + { + ccp next = NextUTF8CharE(str,end); + if ( str == next ) + break; + str = next; + } + } + return (char*)str; +} + +//----------------------------------------------------------------------------- + +char * SkipEUTF8Char ( ccp str, int skip ) +{ + if (str) + { + if ( skip < 0 ) + skip += ScanEUTF8Length(str); + while ( skip-- > 0 ) + { + ccp next = NextEUTF8Char(str); + if ( str == next ) + break; + str = next; + } + } + return (char*)str; +} + +//----------------------------------------------------------------------------- + +char * SkipEUTF8CharE ( ccp str, ccp end, int skip ) +{ + if (str) + { + if ( skip < 0 ) + skip += ScanEUTF8LengthE(str,end); + while ( skip-- > 0 ) + { + ccp next = NextEUTF8CharE(str,end); + if ( str == next ) + break; + str = next; + } + } + return (char*)str; +} + +/////////////////////////////////////////////////////////////////////////////// + u32 GetUTF8Char ( ccp str ) { // fast scan of a UTF8 char -> ignore errors in continuation bytes @@ -698,12 +788,57 @@ u32 ScanUTF8AnsiCharE ( ccp * p_str, ccp end ) /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -int ScanUTF8Length ( ccp str, ccp end ) +int ScanUTF8Length ( ccp str ) { int count = 0; - ccp ptr = str; - if (end) + if (str) + { + ccp ptr = str; + for(;;) + { + const char ch = *ptr++; + if (!ch) + break; + switch (CheckUTF8Mode(ch)) + { + case DC_UTF8_2CHAR: + if ( CheckUTF8Mode(*ptr) == DC_UTF8_CONT_ANY ) + ptr++; + break; + + case DC_UTF8_3CHAR: + if ( CheckUTF8Mode(ptr[0]) == DC_UTF8_CONT_ANY + && CheckUTF8Mode(ptr[1]) == DC_UTF8_CONT_ANY ) + ptr += 2; + break; + + case DC_UTF8_4CHAR: + if ( CheckUTF8Mode(ptr[0]) == DC_UTF8_CONT_ANY + && CheckUTF8Mode(ptr[1]) == DC_UTF8_CONT_ANY + && CheckUTF8Mode(ptr[2]) == DC_UTF8_CONT_ANY ) + ptr += 3; + break; + + default: + break; + } + count++; + } + } + return count; +} + +//----------------------------------------------------------------------------- + +int ScanUTF8LengthE ( ccp str, ccp end ) +{ + if (!end) + return ScanUTF8Length(str); + + int count = 0; + if (str) { + ccp ptr = str; while ( ptr < end ) { const char ch = *ptr++; @@ -733,13 +868,78 @@ int ScanUTF8Length ( ccp str, ccp end ) count++; } } - else + return count; +} + +//----------------------------------------------------------------------------- + +int ScanEUTF8Length ( ccp str ) +{ + int count = 0; + if (str) { + ccp ptr = str; for(;;) { const char ch = *ptr++; if (!ch) break; + + if ( ch == '\e' ) + { + ptr = SkipEscapes(ptr-1); + continue; + } + + switch (CheckUTF8Mode(ch)) + { + case DC_UTF8_2CHAR: + if ( CheckUTF8Mode(*ptr) == DC_UTF8_CONT_ANY ) + ptr++; + break; + + case DC_UTF8_3CHAR: + if ( CheckUTF8Mode(ptr[0]) == DC_UTF8_CONT_ANY + && CheckUTF8Mode(ptr[1]) == DC_UTF8_CONT_ANY ) + ptr += 2; + break; + + case DC_UTF8_4CHAR: + if ( CheckUTF8Mode(ptr[0]) == DC_UTF8_CONT_ANY + && CheckUTF8Mode(ptr[1]) == DC_UTF8_CONT_ANY + && CheckUTF8Mode(ptr[2]) == DC_UTF8_CONT_ANY ) + ptr += 3; + break; + + default: + break; + } + count++; + } + } + return count; +} + +//----------------------------------------------------------------------------- + +int ScanEUTF8LengthE ( ccp str, ccp end ) +{ + if (!end) + return ScanEUTF8Length(str); + + int count = 0; + if (str) + { + ccp ptr = str; + while ( ptr < end ) + { + const char ch = *ptr++; + if ( ch == '\e' ) + { + ptr = SkipEscapesE(ptr-1,end); + continue; + } + switch (CheckUTF8Mode(ch)) { case DC_UTF8_2CHAR: @@ -775,7 +975,7 @@ int ScanUTF8Length ( ccp str, ccp end ) int CalcUTF8PrintFW ( ccp str, ccp end, uint wanted_fw ) { const uint bytecount = end ? end - str : strlen(str); - const uint utf8len = ScanUTF8Length(str,end); + const uint utf8len = ScanUTF8LengthE(str,end); return utf8len < wanted_fw ? wanted_fw - utf8len + bytecount : bytecount; @@ -853,6 +1053,74 @@ char * PrintUTF8CharToCircBuf ( u32 code ) return buf; } +/////////////////////////////////////////////////////////////////////////////// + +ccp AlignUTF8ToCircBuf ( ccp str, int fw, int prec ) +{ + uint len = ScanUTF8Length(str); + if ( prec >= 0 && len > prec ) + len = prec; + + const int align_left = fw < 0; + if ( align_left) + fw = -fw; + if ( fw < len ) + fw = len; + int spaces = fw - len; + + ccp end = SkipUTF8Char(str,len); + const int copy_len = end - str; + + char *buf = GetCircBuf(copy_len+spaces+1); + DASSERT(buf); + if (align_left) + { + memcpy(buf,str,copy_len); + memset(buf+copy_len,' ',spaces); + } + else + { + memset(buf,' ',spaces); + memcpy(buf+spaces,str,copy_len); + } + buf[copy_len+spaces] = 0; + return buf; +} + +/////////////////////////////////////////////////////////////////////////////// + +ccp AlignEUTF8ToCircBuf ( ccp str, int fw, int prec ) +{ + uint len = ScanEUTF8Length(str); + if ( prec >= 0 && len > prec ) + len = prec; + + const int align_left = fw < 0; + if ( align_left) + fw = -fw; + if ( fw < len ) + fw = len; + int spaces = fw - len; + + ccp end = SkipEUTF8Char(str,len); + const int copy_len = end - str; + + char *buf = GetCircBuf(copy_len+spaces+1); + DASSERT(buf); + if (align_left) + { + memcpy(buf,str,copy_len); + memset(buf+copy_len,' ',spaces); + } + else + { + memset(buf,' ',spaces); + memcpy(buf+spaces,str,copy_len); + } + buf[copy_len+spaces] = 0; + return buf; +} + // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// |
