aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2022-10-19 13:36:08 +1100
committerNeil <nyamatongwe@gmail.com>2022-10-19 13:36:08 +1100
commite9280bf01239e81b01899992647766d0c073253b (patch)
tree924d5f1a128552bf8c0b92f8c579544f34edc0ed
parent19a781319ccc6c9de302182e141383ba73403030 (diff)
downloadscintilla-mirror-e9280bf01239e81b01899992647766d0c073253b.tar.gz
Feature [feature-requests:#1455] Implement GetStyledTextFull as a 64-bit safe
version of GetStyledText.
-rw-r--r--call/ScintillaCall.cxx4
-rw-r--r--doc/ScintillaDoc.html9
-rw-r--r--doc/ScintillaHistory.html5
-rw-r--r--include/Scintilla.h1
-rw-r--r--include/Scintilla.iface4
-rw-r--r--include/ScintillaCall.h1
-rw-r--r--include/ScintillaMessages.h1
-rwxr-xr-xscripts/HFacer.py27
-rw-r--r--src/Editor.cxx33
-rw-r--r--src/Editor.h1
-rw-r--r--test/ScintillaCallable.py10
-rw-r--r--test/simpleTests.py9
12 files changed, 79 insertions, 26 deletions
diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx
index 434e3fdf0..816f25eb9 100644
--- a/call/ScintillaCall.cxx
+++ b/call/ScintillaCall.cxx
@@ -227,6 +227,10 @@ Position ScintillaCall::GetStyledText(void *tr) {
return CallPointer(Message::GetStyledText, 0, tr);
}
+Position ScintillaCall::GetStyledTextFull(void *tr) {
+ return CallPointer(Message::GetStyledTextFull, 0, tr);
+}
+
bool ScintillaCall::CanRedo() {
return Call(Message::CanRedo);
}
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index fb5d59dfd..f9a973892 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -536,6 +536,7 @@
<a class="message" href="#SCI_GETSTYLEAT">SCI_GETSTYLEAT(position pos) &rarr; int</a><br />
<a class="message" href="#SCI_GETSTYLEINDEXAT">SCI_GETSTYLEINDEXAT(position pos) &rarr; int</a><br />
<a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT(&lt;unused&gt;, Sci_TextRange *tr) &rarr; position</a><br />
+ <a class="message" href="#SCI_GETSTYLEDTEXTFULL">SCI_GETSTYLEDTEXTFULL(&lt;unused&gt;, Sci_TextRangeFull *tr) &rarr; position</a><br />
<a class="message" href="#SCI_RELEASEALLEXTENDEDSTYLES">SCI_RELEASEALLEXTENDEDSTYLES</a><br />
<a class="message" href="#SCI_ALLOCATEEXTENDEDSTYLES">SCI_ALLOCATEEXTENDEDSTYLES(int numberStyles) &rarr; int</a><br />
<a class="message" href="#SCI_TARGETASUTF8">SCI_TARGETASUTF8(&lt;unused&gt;, char *s) &rarr; position</a><br />
@@ -623,15 +624,19 @@
<a class="seealso" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT</a>,
<a class="seealso" href="#SCI_GETTEXT">SCI_GETTEXT</a></code></p>
- <p><b id="SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT(&lt;unused&gt;, <a class="jump" href="#Sci_TextRange">Sci_TextRange</a> *tr) &rarr; position</b><br />
+ <p>
+ <b id="SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT(&lt;unused&gt;, <a class="jump" href="#Sci_TextRange">Sci_TextRange</a> *tr) &rarr; position</b><br />
+ <b id="SCI_GETSTYLEDTEXTFULL">SCI_GETSTYLEDTEXTFULL(&lt;unused&gt;, <a class="jump" href="#Sci_TextRangeFull">Sci_TextRangeFull</a> *tr) &rarr; position</b><br />
This collects styled text into a buffer using two bytes for each cell, with the character at
the lower address of each pair and the style byte at the upper address. Characters between the
positions <code>cpMin</code> and <code>cpMax</code> are copied to <code>lpstrText</code> (see
- <code>struct Sci_TextRange</code> in <code>Scintilla.h</code>). Two 0 bytes are added to the end of
+ <code>struct Sci_TextRange</code> and <code>struct Sci_TextRangeFull</code> in <code>Scintilla.h</code>). Two 0 bytes are added to the end of
the text, so the buffer that <code>lpstrText</code> points at must be at least
<code>2*(cpMax-cpMin)+2</code> bytes long. No check is made for sensible values of
<code>cpMin</code> or <code>cpMax</code>. Positions outside the document return character codes
and style bytes of 0.</p>
+ <p><code>SCI_GETSTYLEDTEXTFULL</code> uses 64-bit positions on all platforms so is safe for documents larger than 2GB.
+ It should always be used in preference to <code>SCI_GETSTYLEDTEXT</code> which will be deprecated in a future release.</p>
<p>See also: <code><a class="seealso" href="#SCI_GETSELTEXT">SCI_GETSELTEXT</a>,
<a class="seealso" href="#SCI_GETLINE">SCI_GETLINE</a>,
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 5a44b84c5..b145692b5 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -587,6 +587,11 @@
<li>
Draw background colour for EOL annotations with standard and boxed visuals.
</li>
+ <li>
+ Add SCI_GETSTYLEDTEXTFULL to support 64-bit document positions on Win32 replacing
+ SCI_GETSTYLEDTEXT which is not safe for huge documents.
+ <a href="https://sourceforge.net/p/scintilla/feature-requests/1455/">Feature #1455</a>.
+ </li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla531.zip">Release 5.3.1</a>
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 03302e293..30760431f 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -63,6 +63,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
#define SCI_SELECTALL 2013
#define SCI_SETSAVEPOINT 2014
#define SCI_GETSTYLEDTEXT 2015
+#define SCI_GETSTYLEDTEXTFULL 2778
#define SCI_CANREDO 2016
#define SCI_MARKERLINEFROMHANDLE 2017
#define SCI_MARKERDELETEHANDLE 2018
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index b03b8c8ca..a527bb9a4 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -154,6 +154,10 @@ fun void SetSavePoint=2014(,)
# Returns the number of bytes in the buffer not including terminating NULs.
fun position GetStyledText=2015(, textrange tr)
+# Retrieve a buffer of cells that can be past 2GB.
+# Returns the number of bytes in the buffer not including terminating NULs.
+fun position GetStyledTextFull=2778(, textrangefull tr)
+
# Are there any redoable actions in the undo history?
fun bool CanRedo=2016(,)
diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h
index 4b8e3c732..9f3b7e40a 100644
--- a/include/ScintillaCall.h
+++ b/include/ScintillaCall.h
@@ -95,6 +95,7 @@ public:
void SelectAll();
void SetSavePoint();
Position GetStyledText(void *tr);
+ Position GetStyledTextFull(void *tr);
bool CanRedo();
Line MarkerLineFromHandle(int markerHandle);
void MarkerDeleteHandle(int markerHandle);
diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h
index 118655689..9d3034f79 100644
--- a/include/ScintillaMessages.h
+++ b/include/ScintillaMessages.h
@@ -34,6 +34,7 @@ enum class Message {
SelectAll = 2013,
SetSavePoint = 2014,
GetStyledText = 2015,
+ GetStyledTextFull = 2778,
CanRedo = 2016,
MarkerLineFromHandle = 2017,
MarkerDeleteHandle = 2018,
diff --git a/scripts/HFacer.py b/scripts/HFacer.py
index cc8467b2c..0d3062f51 100755
--- a/scripts/HFacer.py
+++ b/scripts/HFacer.py
@@ -31,6 +31,8 @@ def printHFile(f):
out.append("#endif")
return out
+showUnused = False
+
def RegenerateAll(root, showMaxID):
f = Face.Face()
f.ReadFromFile(root / "include/Scintilla.iface")
@@ -39,18 +41,19 @@ def RegenerateAll(root, showMaxID):
valueSet = set(int(x) for x in f.values if int(x) < 3000)
maximumID = max(valueSet)
print("Maximum ID is %d" % maximumID)
- #~ valuesUnused = sorted(x for x in range(2001,maximumID) if x not in valueSet)
- #~ print("\nUnused values")
- #~ valueToName = {}
- #~ for name, feature in f.features.items():
- #~ try:
- #~ value = int(feature["Value"])
- #~ valueToName[value] = name
- #~ except ValueError:
- #~ pass
- #~ for v in valuesUnused:
- #~ prev = valueToName.get(v-1, "")
- #~ print(v, prev)
+ if showUnused:
+ valuesUnused = sorted(x for x in range(2001,maximumID) if x not in valueSet)
+ print("\nUnused values")
+ valueToName = {}
+ for name, feature in f.features.items():
+ try:
+ value = int(feature["Value"])
+ valueToName[value] = name
+ except ValueError:
+ pass
+ for v in valuesUnused:
+ prev = valueToName.get(v-1, "")
+ print(v, prev)
if __name__ == "__main__":
RegenerateAll(pathlib.Path(__file__).resolve().parent.parent, True)
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 35148299e..da52d462c 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -5783,6 +5783,17 @@ void Editor::AddStyledText(const char *buffer, Sci::Position appendLength) {
SetEmptySelection(sel.MainCaret() + lengthInserted);
}
+Sci::Position Editor::GetStyledText(char *buffer, Sci::Position cpMin, Sci::Position cpMax) const noexcept {
+ Sci::Position iPlace = 0;
+ for (Sci::Position iChar = cpMin; iChar < cpMax; iChar++) {
+ buffer[iPlace++] = pdoc->CharAt(iChar);
+ buffer[iPlace++] = pdoc->StyleAt(iChar);
+ }
+ buffer[iPlace] = '\0';
+ buffer[iPlace + 1] = '\0';
+ return iPlace;
+}
+
bool Editor::ValidMargin(uptr_t wParam) const noexcept {
return wParam < vs.ms.size();
}
@@ -6588,19 +6599,17 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
pdoc->SetSavePoint();
break;
- case Message::GetStyledText: {
- if (lParam == 0)
- return 0;
- TextRange *tr = static_cast<TextRange *>(PtrFromSPtr(lParam));
- Sci::Position iPlace = 0;
- for (Sci::Position iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) {
- tr->lpstrText[iPlace++] = pdoc->CharAt(iChar);
- tr->lpstrText[iPlace++] = pdoc->StyleAt(iChar);
- }
- tr->lpstrText[iPlace] = '\0';
- tr->lpstrText[iPlace + 1] = '\0';
- return iPlace;
+ case Message::GetStyledText:
+ if (TextRange *tr = static_cast<TextRange *>(PtrFromSPtr(lParam))) {
+ return GetStyledText(tr->lpstrText, tr->chrg.cpMin, tr->chrg.cpMax);
}
+ return 0;
+
+ case Message::GetStyledTextFull:
+ if (TextRangeFull *tr = static_cast<TextRangeFull *>(PtrFromSPtr(lParam))) {
+ return GetStyledText(tr->lpstrText, tr->chrg.cpMin, tr->chrg.cpMax);
+ }
+ return 0;
case Message::CanRedo:
return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0;
diff --git a/src/Editor.h b/src/Editor.h
index 297590f47..140e15a9c 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -598,6 +598,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
Sci::Line WrapCount(Sci::Line line);
void AddStyledText(const char *buffer, Sci::Position appendLength);
+ Sci::Position GetStyledText(char *buffer, Sci::Position cpMin, Sci::Position cpMax) const noexcept;
virtual Scintilla::sptr_t DefWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) = 0;
bool ValidMargin(Scintilla::uptr_t wParam) const noexcept;
diff --git a/test/ScintillaCallable.py b/test/ScintillaCallable.py
index d8d16c7e3..126281aac 100644
--- a/test/ScintillaCallable.py
+++ b/test/ScintillaCallable.py
@@ -172,6 +172,16 @@ class ScintillaCallable:
styledText = tr.lpstrText[:length]
styledText += b"\0" * (length - len(styledText))
return styledText
+ def StyledTextRangeFull(self, start, end):
+ tr = TEXTRANGEFULL()
+ tr.cpMin = start
+ tr.cpMax = end
+ length = 2 * (end - start)
+ tr.lpstrText = ctypes.create_string_buffer(length + 2)
+ self.GetStyledTextFull(0, ctypes.byref(tr))
+ styledText = tr.lpstrText[:length]
+ styledText += b"\0" * (length - len(styledText))
+ return styledText
def FindBytes(self, start, end, s, flags):
ft = FINDTEXT()
ft.cpMin = start
diff --git a/test/simpleTests.py b/test/simpleTests.py
index 92d6a92a7..2b5d3bc0e 100644
--- a/test/simpleTests.py
+++ b/test/simpleTests.py
@@ -62,6 +62,15 @@ class TestSimple(unittest.TestCase):
self.assertEquals(self.ed.GetStyleAt(0), 0)
self.assertEquals(self.ed.StyledTextRange(0, 1), b"x\0")
+ def testStyledTextRangeFull(self):
+ self.assertEquals(self.ed.EndStyled, 0)
+ self.ed.AddStyledText(4, b"x\002y\377")
+ self.assertEquals(self.ed.StyledTextRangeFull(0, 1), b"x\002")
+ self.assertEquals(self.ed.StyledTextRangeFull(1, 2), b"y\377")
+ self.ed.ClearDocumentStyle()
+ self.assertEquals(self.ed.Length, 2)
+ self.assertEquals(self.ed.StyledTextRangeFull(0, 1), b"x\0")
+
def testStyling(self):
self.assertEquals(self.ed.EndStyled, 0)
self.ed.AddStyledText(4, b"x\002y\003")