aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--win32/ScintillaWin.cxx60
1 files changed, 45 insertions, 15 deletions
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 64ca03cfa..a231e2e55 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -1328,12 +1328,28 @@ std::string ScintillaWin::EncodeWString(std::wstring_view wsv) {
}
sptr_t ScintillaWin::GetTextLength() {
- return pdoc->CountUTF16(0, pdoc->Length());
+ if (pdoc->dbcsCodePage == 0 || pdoc->dbcsCodePage == CpUtf8) {
+ return pdoc->CountUTF16(0, pdoc->Length());
+ } else {
+ // Count the number of UTF-16 code units line by line
+ const UINT cpSrc = CodePageOfDocument();
+ const Sci::Line lines = pdoc->LinesTotal();
+ Sci::Position codeUnits = 0;
+ std::string lineBytes;
+ for (Sci::Line line = 0; line < lines; line++) {
+ const Sci::Position start = pdoc->LineStart(line);
+ const Sci::Position width = pdoc->LineStart(line+1) - start;
+ lineBytes.resize(width);
+ pdoc->GetCharRange(lineBytes.data(), start, width);
+ codeUnits += WideCharLenFromMultiByte(cpSrc, lineBytes);
+ }
+ return codeUnits;
+ }
}
sptr_t ScintillaWin::GetText(uptr_t wParam, sptr_t lParam) {
if (lParam == 0) {
- return pdoc->CountUTF16(0, pdoc->Length());
+ return GetTextLength();
}
if (wParam == 0) {
return 0;
@@ -1344,27 +1360,41 @@ sptr_t ScintillaWin::GetText(uptr_t wParam, sptr_t lParam) {
return 0;
}
const Sci::Position lengthWanted = wParam - 1;
- Sci::Position sizeRequestedRange = pdoc->GetRelativePositionUTF16(0, lengthWanted);
- if (sizeRequestedRange < 0) {
- // Requested more text than there is in the document.
- sizeRequestedRange = pdoc->Length();
- }
- std::string docBytes(sizeRequestedRange, '\0');
- pdoc->GetCharRange(&docBytes[0], 0, sizeRequestedRange);
if (IsUnicodeMode()) {
+ Sci::Position sizeRequestedRange = pdoc->GetRelativePositionUTF16(0, lengthWanted);
+ if (sizeRequestedRange < 0) {
+ // Requested more text than there is in the document.
+ sizeRequestedRange = pdoc->Length();
+ }
+ std::string docBytes(sizeRequestedRange, '\0');
+ pdoc->GetCharRange(&docBytes[0], 0, sizeRequestedRange);
const size_t uLen = UTF16FromUTF8(docBytes, ptr, lengthWanted);
ptr[uLen] = L'\0';
return uLen;
} else {
// Not Unicode mode
// Convert to Unicode using the current Scintilla code page
+ // Retrieve as UTF-16 line by line
const UINT cpSrc = CodePageOfDocument();
- int lengthUTF16 = WideCharLenFromMultiByte(cpSrc, docBytes);
- if (lengthUTF16 > lengthWanted)
- lengthUTF16 = static_cast<int>(lengthWanted);
- WideCharFromMultiByte(cpSrc, docBytes, ptr, lengthUTF16);
- ptr[lengthUTF16] = L'\0';
- return lengthUTF16;
+ const Sci::Line lines = pdoc->LinesTotal();
+ Sci::Position codeUnits = 0;
+ std::string lineBytes;
+ std::wstring lineAsUTF16;
+ for (Sci::Line line = 0; line < lines && codeUnits < lengthWanted; line++) {
+ const Sci::Position start = pdoc->LineStart(line);
+ const Sci::Position width = pdoc->LineStart(line + 1) - start;
+ lineBytes.resize(width);
+ pdoc->GetCharRange(lineBytes.data(), start, width);
+ const Sci::Position codeUnitsLine = WideCharLenFromMultiByte(cpSrc, lineBytes);
+ lineAsUTF16.resize(codeUnitsLine);
+ const Sci::Position lengthLeft = lengthWanted - codeUnits;
+ WideCharFromMultiByte(cpSrc, lineBytes, lineAsUTF16.data(), lineAsUTF16.length());
+ const Sci::Position lengthToCopy = std::min(lengthLeft, codeUnitsLine);
+ lineAsUTF16.copy(ptr + codeUnits, lengthToCopy);
+ codeUnits += lengthToCopy;
+ }
+ ptr[codeUnits] = L'\0';
+ return codeUnits;
}
}