aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2022-05-17 08:52:34 +1000
committerNeil <nyamatongwe@gmail.com>2022-05-17 08:52:34 +1000
commit475450c76ceef43a7f5b2c68ed5848baee96b6dc (patch)
tree110ed93d9989eb049ecb0ee2c6fc62692adcefa0
parente107ecdf3f5576e90dc90c69fc57f24d1f499b61 (diff)
downloadscintilla-mirror-475450c76ceef43a7f5b2c68ed5848baee96b6dc.tar.gz
Duplicate APIs to support 64-bit document positions on Win32:
SCI_GETTEXTRANGEFULL, SCI_FINDTEXTFULL, and SCI_FORMATRANGEFULL.
-rw-r--r--call/ScintillaCall.cxx24
-rw-r--r--doc/ScintillaDoc.html63
-rw-r--r--doc/ScintillaHistory.html6
-rw-r--r--include/Scintilla.h27
-rw-r--r--include/Scintilla.iface15
-rw-r--r--include/ScintillaCall.h4
-rw-r--r--include/ScintillaMessages.h3
-rw-r--r--include/ScintillaStructures.h24
-rw-r--r--scripts/ScintillaAPIFacer.py3
-rw-r--r--src/EditView.cxx28
-rw-r--r--src/EditView.h2
-rw-r--r--src/Editor.cxx85
-rw-r--r--src/Editor.h3
-rw-r--r--test/ScintillaCallable.py36
-rw-r--r--test/simpleTests.py17
15 files changed, 304 insertions, 36 deletions
diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx
index cb0d09365..20fb452da 100644
--- a/call/ScintillaCall.cxx
+++ b/call/ScintillaCall.cxx
@@ -16,6 +16,7 @@
#include "ScintillaTypes.h"
#include "ScintillaMessages.h"
#include "ScintillaCall.h"
+#include "ScintillaStructures.h"
namespace Scintilla {
@@ -110,6 +111,17 @@ std::string ScintillaCall::StringOfSpan(Span span) {
}
}
+std::string ScintillaCall::StringOfRange(Span span) {
+ if (span.Length() == 0) {
+ return std::string();
+ } else {
+ std::string text(span.Length(), '\0');
+ TextRangeFull tr{ {span.start, span.end}, text.data() };
+ GetTextRangeFull(&tr);
+ return text;
+ }
+}
+
Position ScintillaCall::ReplaceTarget(std::string_view text) {
return ScintillaCall::CallString(Message::ReplaceTarget, text.length(), text.data());
}
@@ -1127,10 +1139,18 @@ Position ScintillaCall::FindText(Scintilla::FindOption searchFlags, void *ft) {
return CallPointer(Message::FindText, static_cast<uintptr_t>(searchFlags), ft);
}
+Position ScintillaCall::FindTextFull(Scintilla::FindOption searchFlags, void *ft) {
+ return CallPointer(Message::FindTextFull, static_cast<uintptr_t>(searchFlags), ft);
+}
+
Position ScintillaCall::FormatRange(bool draw, void *fr) {
return CallPointer(Message::FormatRange, draw, fr);
}
+Position ScintillaCall::FormatRangeFull(bool draw, void *fr) {
+ return CallPointer(Message::FormatRangeFull, draw, fr);
+}
+
Line ScintillaCall::FirstVisibleLine() {
return Call(Message::GetFirstVisibleLine);
}
@@ -1187,6 +1207,10 @@ Position ScintillaCall::GetTextRange(void *tr) {
return CallPointer(Message::GetTextRange, 0, tr);
}
+Position ScintillaCall::GetTextRangeFull(void *tr) {
+ return CallPointer(Message::GetTextRangeFull, 0, tr);
+}
+
void ScintillaCall::HideSelection(bool hide) {
Call(Message::HideSelection, hide);
}
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index 782f299eb..ea85686aa 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -129,7 +129,7 @@
<h1>Scintilla Documentation</h1>
- <p>Last edited 9 March 2022 NH</p>
+ <p>Last edited 15 May 2022 NH</p>
<p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new
<a href="Lexilla.html">Lexilla</a> project.<br />
@@ -531,6 +531,7 @@
<a class="message" href="#SCI_SETREADONLY">SCI_SETREADONLY(bool readOnly)</a><br />
<a class="message" href="#SCI_GETREADONLY">SCI_GETREADONLY &rarr; bool</a><br />
<a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE(&lt;unused&gt;, Sci_TextRange *tr) &rarr; position</a><br />
+ <a class="message" href="#SCI_GETTEXTRANGEFULL">SCI_GETTEXTRANGEFULL(&lt;unused&gt;, Sci_TextRangeFull *tr) &rarr; position</a><br />
<a class="message" href="#SCI_ALLOCATE">SCI_ALLOCATE(position bytes)</a><br />
<a class="message" href="#SCI_ALLOCATELINES">SCI_ALLOCATELINES(line lines)</a><br />
<a class="message" href="#SCI_ADDTEXT">SCI_ADDTEXT(position length, const char *text)</a><br />
@@ -614,13 +615,17 @@
only, attempts to modify the text cause the <a class="message"
href="#SCN_MODIFYATTEMPTRO"><code>SCN_MODIFYATTEMPTRO</code></a> notification.</p>
- <p><b id="SCI_GETTEXTRANGE">SCI_GETTEXTRANGE(&lt;unused&gt;, <a class="jump" href="#Sci_TextRange">Sci_TextRange</a> *tr) &rarr; position</b><br />
+ <p>
+ <b id="SCI_GETTEXTRANGE">SCI_GETTEXTRANGE(&lt;unused&gt;, <a class="jump" href="#Sci_TextRange">Sci_TextRange</a> *tr) &rarr; position</b><br />
+ <b id="SCI_GETTEXTRANGEFULL">SCI_GETTEXTRANGEFULL(&lt;unused&gt;, <a class="jump" href="#Sci_TextRangeFull">Sci_TextRangeFull</a> *tr) &rarr; position</b><br />
This collects the text between the positions <code>cpMin</code> and <code>cpMax</code> and
copies it to <code>lpstrText</code> (see <code>struct Sci_TextRange</code> in
<code>Scintilla.h</code>). If <code>cpMax</code> is -1, text is returned to the end of the
document. The text is 0 terminated, so you must supply a buffer that is at least 1 character
longer than the number of characters you wish to read. The return value is the length of the
returned text not including the terminating 0.</p>
+ <p><code>SCI_GETTEXTRANGEFULL</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_GETTEXTRANGE</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>,
@@ -721,8 +726,9 @@
These structures are defined to be exactly the same shape as the Win32 <code>TEXTRANGE</code>
and <code>CHARRANGE</code>, so that older code that treats Scintilla as a RichEdit will
work.</p>
- <p>In a future release the type <code>Sci_PositionCR</code> will be redefined to be 64-bits when Scintilla is
- built for 64-bits on all platforms.</p>
+ <p>In a future release, these types will be deprecated.
+ <a class="seealso" href="#SCI_MARGINSETSTYLEOFFSET">SCI_GETTEXTRANGEFULL</a>, <code>Sci_TextRangeFull</code>
+ and <code>Sci_CharacterRangeFull</code> should be used instead.</p>
<pre>
typedef long Sci_PositionCR;
@@ -737,6 +743,23 @@ struct Sci_TextRange {
};
</pre>
+ <p><b id="Sci_TextRangeFull">Sci_TextRangeFull</b> and <b id="Sci_CharacterRangeFull">Sci_CharacterRangeFull</b><br />
+ These structures are the same as <code>Sci_TextRange</code> and <code>Sci_CharacterRange</code> except that positions are
+ always 64-bit in 64-bit builds so will work on documents larger than 2GB.</p>
+<pre>
+typedef ptrdiff_t Sci_Position;
+
+struct Sci_CharacterRangeFull {
+ Sci_Position cpMin;
+ Sci_Position cpMax;
+};
+
+struct Sci_TextRangeFull {
+ struct Sci_CharacterRangeFull chrg;
+ char *lpstrText;
+};
+</pre>
+
<h3 id="EncodedAccess">Specific to GTK, Cocoa and Windows only: Access to encoded text</h3>
<p><b id="SCI_TARGETASUTF8">SCI_TARGETASUTF8(&lt;unused&gt;, char *s) &rarr; position</b><br />
@@ -1033,13 +1056,15 @@ struct Sci_TextRange {
See the documentation of your C++ runtime for details on what is supported.</p>
<code><a class="message" href="#SCI_FINDTEXT">SCI_FINDTEXT(int searchFlags, Sci_TextToFind *ft) &rarr; position</a><br />
+ <a class="message" href="#SCI_FINDTEXTFULL">SCI_FINDTEXTFULL(int searchFlags, Sci_TextToFindFull *ft) &rarr; position</a><br />
<a class="message" href="#SCI_SEARCHANCHOR">SCI_SEARCHANCHOR</a><br />
<a class="message" href="#SCI_SEARCHNEXT">SCI_SEARCHNEXT(int searchFlags, const char *text) &rarr; position</a><br />
<a class="message" href="#SCI_SEARCHPREV">SCI_SEARCHPREV(int searchFlags, const char *text) &rarr; position</a><br />
</code>
<p><b id="SCI_FINDTEXT">SCI_FINDTEXT(int searchFlags, <a class="jump" href="#Sci_TextToFind">Sci_TextToFind</a> *ft) &rarr; position</b><br />
- This message searches for text in the document. It does not use or move the current selection.
+ <b id="SCI_FINDTEXT">SCI_FINDTEXTFULL(int searchFlags, <a class="jump" href="#Sci_TextToFindFull">Sci_TextToFindFull</a> *ft) &rarr; position</b><br />
+ These messages search for text in the document. They do not use or move the current selection.
The <a class="jump" href="#searchFlags"><code class="parameter">searchFlags</code></a> argument controls the
search type, which includes regular expression searches.</p>
@@ -1047,13 +1072,14 @@ struct Sci_TextRange {
search backwards to find the previous occurrence of a search string by setting the end of the
search range before the start.</p>
- <p>The <code>Sci_TextToFind</code> structure is defined in <code>Scintilla.h</code>; set
+ <p>The <code>Sci_TextToFind</code> and <code>Sci_TextToFindFull</code> structures are defined in <code>Scintilla.h</code>; set
<code>chrg.cpMin</code> and <code>chrg.cpMax</code> with the range of positions in the document
to search. You can search backwards by
setting <code>chrg.cpMax</code> less than <code>chrg.cpMin</code>.
Set the <code>lpstrText</code> member of <code>Sci_TextToFind</code> to point at a zero terminated
text string holding the search pattern. If your language makes the use of <code>Sci_TextToFind</code>
- difficult, you should consider using <code>SCI_SEARCHINTARGET</code> instead.</p>
+ difficult, you should consider using <code>SCI_SEARCHINTARGET</code> instead.
+ On 64-bit Win32, <code>SCI_FINDTEXT</code> is limited to the first 2G of text and <code>SCI_FINDTEXTFULL</code> removes this limitation.</p>
<p>The return value is -1 if the search fails or the position of the start of the found text if
it succeeds. The <code>chrgText.cpMin</code> and <code>chrgText.cpMax</code> members of
@@ -1073,6 +1099,16 @@ struct Sci_TextToFind {
};
</pre>
+ <p><b id="Sci_TextToFindFull">Sci_TextToFindFull</b><br />
+ This structure extends <code>Sci_TextToFind</code> to support huge documents on Win32.</p>
+<pre>
+struct Sci_TextToFindFull {
+ struct <a class="jump" href="#Sci_CharacterRangeFull">Sci_CharacterRangeFull</a> chrg; // range to search
+ const char *lpstrText; // the search pattern (zero terminated)
+ struct Sci_CharacterRangeFull chrgText; // returned as position of matching text
+};
+</pre>
+
<p><b id="SCI_SEARCHANCHOR">SCI_SEARCHANCHOR</b><br />
<b id="SCI_SEARCHNEXT">SCI_SEARCHNEXT(int searchFlags, const char *text) &rarr; position</b><br />
<b id="SCI_SEARCHPREV">SCI_SEARCHPREV(int searchFlags, const char *text) &rarr; position</b><br />
@@ -6633,6 +6669,7 @@ struct Sci_TextToFind {
and on Cocoa <code>CGContextRef</code> is used.</p>
<code><a class="message" href="#SCI_FORMATRANGE">SCI_FORMATRANGE(bool draw, Sci_RangeToFormat *fr) &rarr; position</a><br />
+ <a class="message" href="#SCI_FORMATRANGEFULL">SCI_FORMATRANGEFULL(bool draw, Sci_RangeToFormatFull *fr) &rarr; position</a><br />
<a class="message" href="#SCI_SETPRINTMAGNIFICATION">SCI_SETPRINTMAGNIFICATION(int
magnification)</a><br />
<a class="message" href="#SCI_GETPRINTMAGNIFICATION">SCI_GETPRINTMAGNIFICATION &rarr; int</a><br />
@@ -6643,6 +6680,7 @@ struct Sci_TextToFind {
</code>
<p><b id="SCI_FORMATRANGE">SCI_FORMATRANGE(bool draw, Sci_RangeToFormat *fr) &rarr; position</b><br />
+ <b id="SCI_FORMATRANGEFULL">SCI_FORMATRANGEFULL(bool draw, Sci_RangeToFormatFull *fr) &rarr; position</b><br />
This call renders a range of text into a device context. If you use
this for printing, you will probably want to arrange a page header and footer; Scintilla does
not do this for you. See <code>SciTEWin::Print()</code> in <code>SciTEWinDlg.cxx</code> for an
@@ -6651,7 +6689,8 @@ struct Sci_TextToFind {
<p><code class="parameter">draw</code> controls if any output is done. Set this to false if you are paginating
(for example, if you use this with MFC you will need to paginate in
- <code>OnBeginPrinting()</code> before you output each page.</p>
+ <code>OnBeginPrinting()</code> before you output each page.
+ On 64-bit Win32, <code>SCI_FORMATRANGE</code> is limited to the first 2G of text and <code>SCI_FORMATRANGEFULL</code> removes this limitation.</p>
<pre>
struct Sci_Rectangle { int left; int top; int right; int bottom; };
@@ -6662,6 +6701,14 @@ struct Sci_RangeToFormat {
Sci_Rectangle rcPage; // Physically printable page size
Sci_CharacterRange chrg; // Range of characters to print
};
+
+struct Sci_RangeToFormatFull {
+ Sci_SurfaceID hdc; // The Surface ID we print to
+ Sci_SurfaceID hdcTarget; // The Surface ID we use for measuring (may be same as hdc)
+ Sci_Rectangle rc; // Rectangle in which to print
+ Sci_Rectangle rcPage; // Physically printable page size
+ Sci_CharacterRangeFull chrg; // Range of characters to print
+};
</pre>
<p>On Windows, <code>hdc</code> and <code>hdcTarget</code> should both be set to the device context handle
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 772fea3d8..e1db2d4ec 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -581,6 +581,12 @@
Released 31 March 2022.
</li>
<li>
+ Duplicate APIs to support 64-bit document positions on Win32:
+ SCI_GETTEXTRANGEFULL, SCI_FINDTEXTFULL, and SCI_FORMATRANGEFULL.
+ This adds new types to Scintilla.iface which may impact downstream projects.
+ Applications should move to these APIs from their predecessors as they will be deprecated.
+ </li>
+ <li>
Improve performance of SCI_FOLDALL(SC_FOLDACTION_EXPAND) by not lexing whole document
as it does not depend on folding structure.
</li>
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 14f788eae..0a5c46933 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -474,7 +474,9 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
#define SCFIND_POSIX 0x00400000
#define SCFIND_CXX11REGEX 0x00800000
#define SCI_FINDTEXT 2150
+#define SCI_FINDTEXTFULL 2196
#define SCI_FORMATRANGE 2151
+#define SCI_FORMATRANGEFULL 2777
#define SCI_GETFIRSTVISIBLELINE 2152
#define SCI_GETLINE 2153
#define SCI_GETLINECOUNT 2154
@@ -487,6 +489,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
#define SCI_SETSEL 2160
#define SCI_GETSELTEXT 2161
#define SCI_GETTEXTRANGE 2162
+#define SCI_GETTEXTRANGEFULL 2039
#define SCI_HIDESELECTION 2163
#define SCI_POINTXFROMPOSITION 2164
#define SCI_POINTYFROMPOSITION 2165
@@ -1267,17 +1270,33 @@ struct Sci_CharacterRange {
Sci_PositionCR cpMax;
};
+struct Sci_CharacterRangeFull {
+ Sci_Position cpMin;
+ Sci_Position cpMax;
+};
+
struct Sci_TextRange {
struct Sci_CharacterRange chrg;
char *lpstrText;
};
+struct Sci_TextRangeFull {
+ struct Sci_CharacterRangeFull chrg;
+ char *lpstrText;
+};
+
struct Sci_TextToFind {
struct Sci_CharacterRange chrg;
const char *lpstrText;
struct Sci_CharacterRange chrgText;
};
+struct Sci_TextToFindFull {
+ struct Sci_CharacterRangeFull chrg;
+ const char *lpstrText;
+ struct Sci_CharacterRangeFull chrgText;
+};
+
typedef void *Sci_SurfaceID;
struct Sci_Rectangle {
@@ -1298,6 +1317,14 @@ struct Sci_RangeToFormat {
struct Sci_CharacterRange chrg;
};
+struct Sci_RangeToFormatFull {
+ Sci_SurfaceID hdc;
+ Sci_SurfaceID hdcTarget;
+ struct Sci_Rectangle rc;
+ struct Sci_Rectangle rcPage;
+ struct Sci_CharacterRangeFull chrg;
+};
+
#ifndef __cplusplus
/* For the GTK+ platform, g-ir-scanner needs to have these typedefs. This
* is not required in C++ code and actually seems to break ScintillaEditPy */
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index 7c20e9144..be3d78692 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -60,9 +60,12 @@
## cells -> pointer to array of cells, each cell containing a style byte and character byte
## pointer -> void* pointer that may point to a document, loader, internal text storage or similar
## textrange -> range of a min and a max position with an output string
+## textrangefull -> range of a min and a max position with an output string - supports 64-bit
## findtext -> searchrange, text -> foundposition
+## findtextfull -> searchrange, text -> foundposition
## keymod -> integer containing key in low half and modifiers in high half
## formatrange
+## formatrangefull
## Enumeration types always start with a capital letter
## Types no longer used:
## findtextex -> searchrange
@@ -1212,9 +1215,15 @@ ali SCFIND_CXX11REGEX=CXX11_REG_EX
# Find some text in the document.
fun position FindText=2150(FindOption searchFlags, findtext ft)
-# On Windows, will draw the document into a display context such as a printer.
+# Find some text in the document.
+fun position FindTextFull=2196(FindOption searchFlags, findtextfull ft)
+
+# Draw the document into a display context such as a printer.
fun position FormatRange=2151(bool draw, formatrange fr)
+# Draw the document into a display context such as a printer.
+fun position FormatRangeFull=2777(bool draw, formatrangefull fr)
+
# Retrieve the display line at the top of the display.
get line GetFirstVisibleLine=2152(,)
@@ -1255,6 +1264,10 @@ fun position GetSelText=2161(, stringresult text)
# Return the length of the text.
fun position GetTextRange=2162(, textrange tr)
+# Retrieve a range of text that can be past 2GB.
+# Return the length of the text.
+fun position GetTextRangeFull=2039(, textrangefull tr)
+
# Draw the selection either highlighted or in normal (non-highlighted) style.
fun void HideSelection=2163(bool hide,)
diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h
index 83e62d6da..40cf1e576 100644
--- a/include/ScintillaCall.h
+++ b/include/ScintillaCall.h
@@ -68,6 +68,7 @@ public:
char CharacterAt(Position position);
int UnsignedStyleAt(Position position);
std::string StringOfSpan(Span span);
+ std::string StringOfRange(Span span);
Position ReplaceTarget(std::string_view text);
Position ReplaceTargetRE(std::string_view text);
Position SearchInTarget(std::string_view text);
@@ -322,7 +323,9 @@ public:
void SetPrintColourMode(Scintilla::PrintOption mode);
Scintilla::PrintOption PrintColourMode();
Position FindText(Scintilla::FindOption searchFlags, void *ft);
+ Position FindTextFull(Scintilla::FindOption searchFlags, void *ft);
Position FormatRange(bool draw, void *fr);
+ Position FormatRangeFull(bool draw, void *fr);
Line FirstVisibleLine();
Position GetLine(Line line, char *text);
std::string GetLine(Line line);
@@ -337,6 +340,7 @@ public:
Position GetSelText(char *text);
std::string GetSelText();
Position GetTextRange(void *tr);
+ Position GetTextRangeFull(void *tr);
void HideSelection(bool hide);
int PointXFromPosition(Position pos);
int PointYFromPosition(Position pos);
diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h
index d7bec7f75..3b2927472 100644
--- a/include/ScintillaMessages.h
+++ b/include/ScintillaMessages.h
@@ -258,7 +258,9 @@ enum class Message {
SetPrintColourMode = 2148,
GetPrintColourMode = 2149,
FindText = 2150,
+ FindTextFull = 2196,
FormatRange = 2151,
+ FormatRangeFull = 2777,
GetFirstVisibleLine = 2152,
GetLine = 2153,
GetLineCount = 2154,
@@ -271,6 +273,7 @@ enum class Message {
SetSel = 2160,
GetSelText = 2161,
GetTextRange = 2162,
+ GetTextRangeFull = 2039,
HideSelection = 2163,
PointXFromPosition = 2164,
PointYFromPosition = 2165,
diff --git a/include/ScintillaStructures.h b/include/ScintillaStructures.h
index 6bd16e8c1..a3418173f 100644
--- a/include/ScintillaStructures.h
+++ b/include/ScintillaStructures.h
@@ -19,17 +19,33 @@ struct CharacterRange {
PositionCR cpMax;
};
+struct CharacterRangeFull {
+ Position cpMin;
+ Position cpMax;
+};
+
struct TextRange {
CharacterRange chrg;
char *lpstrText;
};
+struct TextRangeFull {
+ CharacterRangeFull chrg;
+ char *lpstrText;
+};
+
struct TextToFind {
CharacterRange chrg;
const char *lpstrText;
CharacterRange chrgText;
};
+struct TextToFindFull {
+ CharacterRangeFull chrg;
+ const char *lpstrText;
+ CharacterRangeFull chrgText;
+};
+
using SurfaceID = void *;
struct Rectangle {
@@ -49,6 +65,14 @@ struct RangeToFormat {
CharacterRange chrg;
};
+struct RangeToFormatFull {
+ SurfaceID hdc;
+ SurfaceID hdcTarget;
+ Rectangle rc;
+ Rectangle rcPage;
+ CharacterRangeFull chrg;
+};
+
struct NotifyHeader {
/* Compatible with Windows NMHDR.
* hwndFrom is really an environment specific window handle or pointer
diff --git a/scripts/ScintillaAPIFacer.py b/scripts/ScintillaAPIFacer.py
index 9fe5f56ce..e30f48380 100644
--- a/scripts/ScintillaAPIFacer.py
+++ b/scripts/ScintillaAPIFacer.py
@@ -19,7 +19,9 @@ typeAliases = {
"colour": "Colour",
"colouralpha": "ColourAlpha",
"findtext": "void *",
+ "findtextfull": "void *",
"formatrange": "void *",
+ "formatrangefull": "void *",
"int": "int",
"keymod": "int",
"line": "Line",
@@ -28,6 +30,7 @@ typeAliases = {
"string": "const char *",
"stringresult": "char *",
"textrange": "void *",
+ "textrangefull": "void *",
}
basicTypes = [
diff --git a/src/EditView.cxx b/src/EditView.cxx
index d4ab63948..2ba450ab3 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -2668,7 +2668,7 @@ static ColourRGBA InvertedLight(ColourRGBA orig) noexcept {
return ColourRGBA(std::min(r, 0xffu), std::min(g, 0xffu), std::min(b, 0xffu));
}
-Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure,
+Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangle rc, Surface *surface, Surface *surfaceMeasure,
const EditModel &model, const ViewStyle &vs) {
// Can't use measurements cached for screen
posCache->Clear();
@@ -2733,15 +2733,15 @@ Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface
vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars); // Recalculate fixedColumnWidth
}
- const Sci::Line linePrintStart = model.pdoc->SciLineFromPosition(pfr->chrg.cpMin);
- Sci::Line linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1;
+ const Sci::Line linePrintStart = model.pdoc->SciLineFromPosition(chrg.cpMin);
+ Sci::Line linePrintLast = linePrintStart + (rc.bottom - rc.top) / vsPrint.lineHeight - 1;
if (linePrintLast < linePrintStart)
linePrintLast = linePrintStart;
- const Sci::Line linePrintMax = model.pdoc->SciLineFromPosition(pfr->chrg.cpMax);
+ const Sci::Line linePrintMax = model.pdoc->SciLineFromPosition(chrg.cpMax);
if (linePrintLast > linePrintMax)
linePrintLast = linePrintMax;
//Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n",
- // linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight,
+ // linePrintStart, linePrintLast, linePrintMax, rc.top, rc.bottom, vsPrint.lineHeight,
// surfaceMeasure->Height(vsPrint.styles[StyleLineNumber].font));
Sci::Position endPosPrint = model.pdoc->Length();
if (linePrintLast < model.pdoc->LinesTotal())
@@ -2750,18 +2750,18 @@ Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface
// Ensure we are styled to where we are formatting.
model.pdoc->EnsureStyledTo(endPosPrint);
- const int xStart = vsPrint.fixedColumnWidth + pfr->rc.left;
- int ypos = pfr->rc.top;
+ const int xStart = vsPrint.fixedColumnWidth + rc.left;
+ int ypos = rc.top;
Sci::Line lineDoc = linePrintStart;
- Sci::Position nPrintPos = pfr->chrg.cpMin;
+ Sci::Position nPrintPos = chrg.cpMin;
int visibleLine = 0;
- int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth;
+ int widthPrint = rc.right - rc.left - vsPrint.fixedColumnWidth;
if (printParameters.wrapState == Wrap::None)
widthPrint = LineLayout::wrapWidthInfinite;
- while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) {
+ while (lineDoc <= linePrintLast && ypos < rc.bottom) {
// When printing, the hdc and hdcTarget may be the same, so
// changing the state of surfaceMeasure may change the underlying
@@ -2777,9 +2777,9 @@ Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface
ll.containsCaret = false;
PRectangle rcLine = PRectangle::FromInts(
- pfr->rc.left,
+ rc.left,
ypos,
- pfr->rc.right - 1,
+ rc.right - 1,
ypos + vsPrint.lineHeight);
// When document line is wrapped over multiple display lines, find where
@@ -2800,7 +2800,7 @@ Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface
}
if (draw && lineNumberWidth &&
- (ypos + vsPrint.lineHeight <= pfr->rc.bottom) &&
+ (ypos + vsPrint.lineHeight <= rc.bottom) &&
(visibleLine >= 0)) {
const std::string number = std::to_string(lineDoc + 1) + lineNumberPrintSpace;
PRectangle rcNumber = rcLine;
@@ -2819,7 +2819,7 @@ Sci::Position EditView::FormatRange(bool draw, const RangeToFormat *pfr, Surface
surface->FlushCachedState();
for (int iwl = 0; iwl < ll.lines; iwl++) {
- if (ypos + vsPrint.lineHeight <= pfr->rc.bottom) {
+ if (ypos + vsPrint.lineHeight <= rc.bottom) {
if (visibleLine >= 0) {
if (draw) {
rcLine.top = static_cast<XYPOSITION>(ypos);
diff --git a/src/EditView.h b/src/EditView.h
index 199a174b9..d65bf0736 100644
--- a/src/EditView.h
+++ b/src/EditView.h
@@ -160,7 +160,7 @@ public:
const ViewStyle &vsDraw);
void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, PRectangle rcArea, int subLine) const;
- Sci::Position FormatRange(bool draw, const Scintilla::RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure,
+ Sci::Position FormatRange(bool draw, CharacterRangeFull chrg, Rectangle rc, Surface *surface, Surface *surfaceMeasure,
const EditModel &model, const ViewStyle &vs);
};
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 6ec2dea3e..f99914ebd 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -1834,18 +1834,30 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
// This is mostly copied from the Paint method but with some things omitted
// such as the margin markers, line numbers, selection and caret
// Should be merged back into a combined Draw method.
-Sci::Position Editor::FormatRange(bool draw, const RangeToFormat *pfr) {
- if (!pfr)
- return 0;
-
- AutoSurface surface(pfr->hdc, this, Technology::Default);
- if (!surface)
- return 0;
- AutoSurface surfaceMeasure(pfr->hdcTarget, this, Technology::Default);
- if (!surfaceMeasure) {
+Sci::Position Editor::FormatRange(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) {
+ if (!lParam)
return 0;
+ const bool draw = wParam != 0;
+ void *ptr = PtrFromSPtr(lParam);
+ if (iMessage == Message::FormatRange) {
+ RangeToFormat *pfr = static_cast<RangeToFormat *>(ptr);
+ CharacterRangeFull chrg{ pfr->chrg.cpMin,pfr->chrg.cpMax };
+ AutoSurface surface(pfr->hdc, this, Technology::Default);
+ AutoSurface surfaceMeasure(pfr->hdcTarget, this, Technology::Default);
+ if (!surface || !surfaceMeasure) {
+ return 0;
+ }
+ return view.FormatRange(draw, chrg, pfr->rc, surface, surfaceMeasure, *this, vs);
+ } else {
+ // FormatRangeFull
+ RangeToFormatFull *pfr = static_cast<RangeToFormatFull *>(ptr);
+ AutoSurface surface(pfr->hdc, this, Technology::Default);
+ AutoSurface surfaceMeasure(pfr->hdcTarget, this, Technology::Default);
+ if (!surface || !surfaceMeasure) {
+ return 0;
+ }
+ return view.FormatRange(draw, pfr->chrg, pfr->rc, surface, surfaceMeasure, *this, vs);
}
- return view.FormatRange(draw, pfr, surface, surfaceMeasure, *this, vs);
}
long Editor::TextWidth(uptr_t style, const char *text) {
@@ -4121,6 +4133,37 @@ Sci::Position Editor::FindText(
}
/**
+ * Search of a text in the document, in the given range.
+ * @return The position of the found text, -1 if not found.
+ */
+Sci::Position Editor::FindTextFull(
+ uptr_t wParam, ///< Search modes : @c FindOption::MatchCase, @c FindOption::WholeWord,
+ ///< @c FindOption::WordStart, @c FindOption::RegExp or @c FindOption::Posix.
+ sptr_t lParam) { ///< @c Sci_TextToFindFull structure: The text to search for in the given range.
+
+ TextToFindFull *ft = static_cast<TextToFindFull *>(PtrFromSPtr(lParam));
+ Sci::Position lengthFound = strlen(ft->lpstrText);
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
+ try {
+ const Sci::Position pos = pdoc->FindText(
+ static_cast<Sci::Position>(ft->chrg.cpMin),
+ static_cast<Sci::Position>(ft->chrg.cpMax),
+ ft->lpstrText,
+ static_cast<FindOption>(wParam),
+ &lengthFound);
+ if (pos != -1) {
+ ft->chrgText.cpMin = static_cast<Sci_PositionCR>(pos);
+ ft->chrgText.cpMax = static_cast<Sci_PositionCR>(pos + lengthFound);
+ }
+ return pos;
+ } catch (RegexError &) {
+ errorStatus = Status::RegEx;
+ return -1;
+ }
+}
+
+/**
* Relocatable search support : Searches relative to current selection
* point and sets the selection to the found text range with
* each search.
@@ -6244,6 +6287,9 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::FindText:
return FindText(wParam, lParam);
+ case Message::FindTextFull:
+ return FindTextFull(wParam, lParam);
+
case Message::GetTextRange: {
if (lParam == 0)
return 0;
@@ -6259,13 +6305,30 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
return len; // Not including NUL
}
+ case Message::GetTextRangeFull: {
+ if (lParam == 0)
+ return 0;
+ TextRangeFull *tr = static_cast<TextRangeFull *>(PtrFromSPtr(lParam));
+ Sci::Position cpMax = tr->chrg.cpMax;
+ if (cpMax == -1)
+ cpMax = pdoc->Length();
+ PLATFORM_ASSERT(cpMax <= pdoc->Length());
+ const Sci::Position len = cpMax - tr->chrg.cpMin; // No -1 as cpMin and cpMax are referring to inter character positions
+ PLATFORM_ASSERT(len >= 0);
+ pdoc->GetCharRange(tr->lpstrText, tr->chrg.cpMin, len);
+ // Spec says copied text is terminated with a NUL
+ tr->lpstrText[len] = '\0';
+ return len; // Not including NUL
+ }
+
case Message::HideSelection:
view.hideSelection = wParam != 0;
Redraw();
break;
case Message::FormatRange:
- return FormatRange(wParam != 0, static_cast<RangeToFormat *>(PtrFromSPtr(lParam)));
+ case Message::FormatRangeFull:
+ return FormatRange(iMessage, wParam, lParam);
case Message::GetMarginLeft:
return vs.leftMarginWidth;
diff --git a/src/Editor.h b/src/Editor.h
index 095131c76..a6364be4d 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -406,7 +406,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void PaintSelMargin(Surface *surfaceWindow, const PRectangle &rc);
void RefreshPixMaps(Surface *surfaceWindow);
void Paint(Surface *surfaceWindow, PRectangle rcArea);
- Sci::Position FormatRange(bool draw, const Scintilla::RangeToFormat *pfr);
+ Sci::Position FormatRange(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
long TextWidth(Scintilla::uptr_t style, const char *text);
virtual void SetVerticalScrollPos() = 0;
@@ -503,6 +503,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual std::unique_ptr<CaseFolder> CaseFolderForEncoding();
Sci::Position FindText(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
+ Sci::Position FindTextFull(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
void SearchAnchor();
Sci::Position SearchText(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
Sci::Position SearchInTarget(const char *text, Sci::Position length);
diff --git a/test/ScintillaCallable.py b/test/ScintillaCallable.py
index 1164631ae..d8d16c7e3 100644
--- a/test/ScintillaCallable.py
+++ b/test/ScintillaCallable.py
@@ -21,6 +21,13 @@ class TEXTRANGE(ctypes.Structure):
('lpstrText', ctypes.POINTER(ctypes.c_char)),
)
+class TEXTRANGEFULL(ctypes.Structure):
+ _fields_= (\
+ ('cpMin', c_ssize_t),
+ ('cpMax', c_ssize_t),
+ ('lpstrText', ctypes.POINTER(ctypes.c_char)),
+ )
+
class FINDTEXT(ctypes.Structure):
_fields_= (\
('cpMin', c_long),
@@ -30,6 +37,15 @@ class FINDTEXT(ctypes.Structure):
('cpMaxText', c_long),
)
+class FINDTEXTFULL(ctypes.Structure):
+ _fields_= (\
+ ('cpMin', c_ssize_t),
+ ('cpMax', c_ssize_t),
+ ('lpstrText', c_char_p),
+ ('cpMinText', c_ssize_t),
+ ('cpMaxText', c_ssize_t),
+ )
+
class SciCall:
def __init__(self, fn, ptr, msg, stringResult=False):
self._fn = fn
@@ -136,6 +152,16 @@ class ScintillaCallable:
text = tr.lpstrText[:length]
text += b"\0" * (length - len(text))
return text
+ def ByteRangeFull(self, start, end):
+ tr = TEXTRANGEFULL()
+ tr.cpMin = start
+ tr.cpMax = end
+ length = end - start
+ tr.lpstrText = ctypes.create_string_buffer(length + 1)
+ self.GetTextRangeFull(0, ctypes.byref(tr))
+ text = tr.lpstrText[:length]
+ text += b"\0" * (length - len(text))
+ return text
def StyledTextRange(self, start, end):
tr = TEXTRANGE()
tr.cpMin = start
@@ -156,6 +182,16 @@ class ScintillaCallable:
pos = self.FindText(flags, ctypes.byref(ft))
#~ print(start, end, ft.cpMinText, ft.cpMaxText)
return pos
+ def FindBytesFull(self, start, end, s, flags):
+ ft = FINDTEXTFULL()
+ ft.cpMin = start
+ ft.cpMax = end
+ ft.lpstrText = s
+ ft.cpMinText = 0
+ ft.cpMaxText = 0
+ pos = self.FindTextFull(flags, ctypes.byref(ft))
+ #~ print(start, end, ft.cpMinText, ft.cpMaxText)
+ return pos
def Contents(self):
return self.ByteRange(0, self.Length)
diff --git a/test/simpleTests.py b/test/simpleTests.py
index 7b326f8e0..195479eaa 100644
--- a/test/simpleTests.py
+++ b/test/simpleTests.py
@@ -165,6 +165,17 @@ class TestSimple(unittest.TestCase):
self.assertEquals(self.ed.Length, 4)
self.assertEquals(b"xxyy", self.ed.ByteRange(0,4))
+ def testTextRangeFull(self):
+ data = b"xy"
+ self.ed.InsertText(0, data)
+ self.assertEquals(self.ed.Length, 2)
+ self.assertEquals(data, self.ed.ByteRangeFull(0,2))
+
+ self.ed.InsertText(1, data)
+ # Should now be "xxyy"
+ self.assertEquals(self.ed.Length, 4)
+ self.assertEquals(b"xxyy", self.ed.ByteRangeFull(0,4))
+
def testInsertNul(self):
data = b"\0"
self.ed.AddText(1, data)
@@ -1187,6 +1198,12 @@ class TestSearch(unittest.TestCase):
pos = self.ed.FindBytes(0, self.ed.Length, b"big", 0)
self.assertEquals(pos, 2)
+ def testFindFull(self):
+ pos = self.ed.FindBytesFull(0, self.ed.Length, b"zzz", 0)
+ self.assertEquals(pos, -1)
+ pos = self.ed.FindBytesFull(0, self.ed.Length, b"big", 0)
+ self.assertEquals(pos, 2)
+
def testFindEmpty(self):
pos = self.ed.FindBytes(0, self.ed.Length, b"", 0)
self.assertEquals(pos, 0)