diff options
-rw-r--r-- | gtk/PlatGTK.cxx | 8 | ||||
-rw-r--r-- | include/Platform.h | 2 | ||||
-rw-r--r-- | src/Document.cxx | 62 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 8 |
4 files changed, 59 insertions, 21 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index ebf949566..abcc0d486 100644 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -1697,6 +1697,14 @@ bool Platform::IsDBCSLeadByte(int /*codePage*/, char /*ch*/) { return false; } +int Platform::DBCSCharLength(int codePage, const char *s) { + return mblen(s, MB_CUR_MAX) +} + +int Platform::DBCSCharMaxLength() { + return MB_CUR_MAX; +} + // These are utility functions not really tied to a platform int Platform::Minimum(int a, int b) { diff --git a/include/Platform.h b/include/Platform.h index 9061449e2..4096cb140 100644 --- a/include/Platform.h +++ b/include/Platform.h @@ -446,6 +446,8 @@ public: static long SendScintillaPointer( WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); static bool IsDBCSLeadByte(int codePage, char ch); + static int DBCSCharLength(int codePage, const char *s); + static int DBCSCharMaxLength(); // These are utility functions not really tied to a platform static int Minimum(int a, int b); diff --git a/src/Document.cxx b/src/Document.cxx index 5afd34625..7a5ce2fa8 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -218,6 +218,8 @@ bool Document::IsCrLf(int pos) { return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } +static const int maxBytesInDBCSCharacter=5; + bool Document::IsDBCS(int pos) { if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { @@ -227,11 +229,18 @@ bool Document::IsDBCS(int pos) { // Anchor DBCS calculations at start of line because start of line can // not be a DBCS trail byte. int startLine = pos; + char mbstr[maxBytesInDBCSCharacter+1]; while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n') startLine--; while (startLine <= pos) { - if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine))) { - startLine++; + int i; + for (i=0; i<Platform::DBCSCharMaxLength(); i++) { + mbstr[i] = cb.CharAt(startLine+i); + } + mbstr[i] = '\0'; + int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr); + if (mbsize >= 1) { + startLine += mbsize; if (startLine >= pos) return true; } @@ -257,8 +266,14 @@ int Document::LenChar(int pos) { return lengthDoc -pos; else return len; - } else if (IsDBCS(pos)) { - return 2; + } else if (dbcsCodePage) { + char mbstr[maxBytesInDBCSCharacter+1]; + int i; + for (i=0; i<Platform::DBCSCharMaxLength(); i++) { + mbstr[i] = cb.CharAt(pos+i); + } + mbstr[i] = '\0'; + return Platform::DBCSCharLength(dbcsCodePage, mbstr); } else { return 1; } @@ -308,27 +323,32 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { // Anchor DBCS calculations at start of line because start of line can // not be a DBCS trail byte. int startLine = pos; + while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n') startLine--; - bool atLeadByte = false; - while (startLine < pos) { - if (atLeadByte) - atLeadByte = false; - else if (Platform::IsDBCSLeadByte(dbcsCodePage, cb.CharAt(startLine))) - atLeadByte = true; - else - atLeadByte = false; + for (;startLine <= pos;) { + char mbstr[maxBytesInDBCSCharacter+1]; + int i; + for(i=0;i<Platform::DBCSCharMaxLength();i++) { + mbstr[i] = cb.CharAt(startLine+i); + } + mbstr[i] = '\0'; + + int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr); + if (mbsize >= 1) { + if (startLine + mbsize == pos) { + return pos; + } else if (startLine + mbsize > pos) { + if (moveDir > 0) + return startLine + mbsize; + else + return startLine; + } + startLine += mbsize; + continue; + } startLine++; } - - - if (atLeadByte) { - // Position is between a lead byte and a trail byte - if (moveDir > 0) - return pos + 1; - else - return pos - 1; - } } } diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 6e2ff1b1a..546b278db 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -1271,6 +1271,14 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) { return ::IsDBCSLeadByteEx(codePage, ch) != 0; } +int Platform::DBCSCharLength(int codePage, const char *s) { + return (::IsDBCSLeadByteEx(codePage, s[0]) != 0) ? 2 : 1; +} + +int Platform::DBCSCharMaxLength() { + return 2; +} + // These are utility functions not really tied to a platform int Platform::Minimum(int a, int b) { |