From 220097c92ac29076cef98528e15968e9385855dc Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 12 Jan 2023 10:17:18 +0100 Subject: [PATCH] Update Scintilla to 5.3.2 Signed-off-by: Sven Strickroth --- ext/scintilla/cppcheck.suppress | 4 + ext/scintilla/include/Scintilla.h | 5 +- ext/scintilla/include/Scintilla.iface | 9 ++ ext/scintilla/include/ScintillaCall.h | 3 + ext/scintilla/include/ScintillaMessages.h | 2 + ext/scintilla/include/ScintillaTypes.h | 1 + ext/scintilla/src/CaseConvert.cxx | 195 +++++++++++++---------------- ext/scintilla/src/CharacterCategoryMap.cxx | 190 ++++++++++++++++++++-------- ext/scintilla/src/Document.cxx | 116 +++++++++-------- ext/scintilla/src/Document.h | 50 +++++--- ext/scintilla/src/EditView.cxx | 51 ++++---- ext/scintilla/src/EditView.h | 1 - ext/scintilla/src/Editor.cxx | 121 ++++++++++-------- ext/scintilla/src/Editor.h | 13 +- ext/scintilla/src/ScintillaBase.cxx | 41 ++++-- ext/scintilla/src/ScintillaBase.h | 3 +- ext/scintilla/version.txt | 2 +- ext/scintilla/win32/PlatWin.cxx | 89 ++++++++++--- ext/scintilla/win32/PlatWin.h | 17 +++ ext/scintilla/win32/ScintRes.rc | 4 +- ext/scintilla/win32/ScintillaWin.cxx | 62 +++++---- ext/scintilla/win32/makefile | 2 +- ext/scintilla/win32/scintilla.mak | 2 +- 23 files changed, 604 insertions(+), 379 deletions(-) diff --git a/ext/scintilla/cppcheck.suppress b/ext/scintilla/cppcheck.suppress index 2515e8978..2d767ee2f 100644 --- a/ext/scintilla/cppcheck.suppress +++ b/ext/scintilla/cppcheck.suppress @@ -13,6 +13,10 @@ useStlAlgorithm // Written with variable for consistency knownArgument:scintilla/src/SparseVector.h +// The cast converts from 'unsigned char ' to 'char' so isn't unused. +// Redundant code: Found unused cast of expression 'leadByte' +constStatement:scintilla/src/Document.cxx + // Some non-explicit constructors are used for conversions or are private to lexers noExplicitConstructor diff --git a/ext/scintilla/include/Scintilla.h b/ext/scintilla/include/Scintilla.h index 899669fc9..92919bbae 100644 --- a/ext/scintilla/include/Scintilla.h +++ b/ext/scintilla/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 @@ -556,6 +557,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_TARGETWHOLEDOCUMENT 2690 #define SCI_REPLACETARGET 2194 #define SCI_REPLACETARGETRE 2195 +#define SCI_REPLACETARGETMINIMAL 2779 #define SCI_SEARCHINTARGET 2197 #define SCI_SETSEARCHFLAGS 2198 #define SCI_GETSEARCHFLAGS 2199 @@ -1239,6 +1241,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_AC_TAB 3 #define SC_AC_NEWLINE 4 #define SC_AC_COMMAND 5 +#define SC_AC_SINGLE_CHOICE 6 #define SC_CHARACTERSOURCE_DIRECT_INPUT 0 #define SC_CHARACTERSOURCE_TENTATIVE_INPUT 1 #define SC_CHARACTERSOURCE_IME_RESULT 2 @@ -1285,8 +1288,6 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #endif -#define SCN_GETBKCOLOR 5000 - /* These structures are defined to be exactly the same shape as the Win32 * CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs. * So older code that treats Scintilla as a RichEdit will work. */ diff --git a/ext/scintilla/include/Scintilla.iface b/ext/scintilla/include/Scintilla.iface index 768a28733..b3bea767f 100644 --- a/ext/scintilla/include/Scintilla.iface +++ b/ext/scintilla/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(,) @@ -1446,6 +1450,10 @@ fun position ReplaceTarget=2194(position length, string text) # caused by processing the \d patterns. fun position ReplaceTargetRE=2195(position length, string text) +# Replace the target text with the argument text but ignore prefix and suffix that +# are the same as current. +fun position ReplaceTargetMinimal=2779(position length, string text) + # Search for a counted string in the target and set the target to the found # range. Text is counted so it can contain NULs. # Returns start of found range or -1 for failure in which case target is not moved. @@ -3346,6 +3354,7 @@ val SC_AC_DOUBLECLICK=2 val SC_AC_TAB=3 val SC_AC_NEWLINE=4 val SC_AC_COMMAND=5 +val SC_AC_SINGLE_CHOICE=6 ali SC_AC_FILLUP=FILL_UP ali SC_AC_DOUBLECLICK=DOUBLE_CLICK diff --git a/ext/scintilla/include/ScintillaCall.h b/ext/scintilla/include/ScintillaCall.h index 0daa2acc2..304b89e4b 100644 --- a/ext/scintilla/include/ScintillaCall.h +++ b/ext/scintilla/include/ScintillaCall.h @@ -71,6 +71,7 @@ public: std::string StringOfRange(Span span); Position ReplaceTarget(std::string_view text); Position ReplaceTargetRE(std::string_view text); + Position ReplaceTargetMinimal(std::string_view text); Position SearchInTarget(std::string_view text); Span SpanSearchInTarget(std::string_view text); @@ -95,6 +96,7 @@ public: void SelectAll(); void SetSavePoint(); Position GetStyledText(void *tr); + Position GetStyledTextFull(void *tr); bool CanRedo(); Line MarkerLineFromHandle(int markerHandle); void MarkerDeleteHandle(int markerHandle); @@ -392,6 +394,7 @@ public: void TargetWholeDocument(); Position ReplaceTarget(Position length, const char *text); Position ReplaceTargetRE(Position length, const char *text); + Position ReplaceTargetMinimal(Position length, const char *text); Position SearchInTarget(Position length, const char *text); void SetSearchFlags(Scintilla::FindOption searchFlags); Scintilla::FindOption SearchFlags(); diff --git a/ext/scintilla/include/ScintillaMessages.h b/ext/scintilla/include/ScintillaMessages.h index 29490dcbf..e6afe4c17 100644 --- a/ext/scintilla/include/ScintillaMessages.h +++ b/ext/scintilla/include/ScintillaMessages.h @@ -34,6 +34,7 @@ enum class Message { SelectAll = 2013, SetSavePoint = 2014, GetStyledText = 2015, + GetStyledTextFull = 2778, CanRedo = 2016, MarkerLineFromHandle = 2017, MarkerDeleteHandle = 2018, @@ -322,6 +323,7 @@ enum class Message { TargetWholeDocument = 2690, ReplaceTarget = 2194, ReplaceTargetRE = 2195, + ReplaceTargetMinimal = 2779, SearchInTarget = 2197, SetSearchFlags = 2198, GetSearchFlags = 2199, diff --git a/ext/scintilla/include/ScintillaTypes.h b/ext/scintilla/include/ScintillaTypes.h index 4bb23c0e8..6219f2b59 100644 --- a/ext/scintilla/include/ScintillaTypes.h +++ b/ext/scintilla/include/ScintillaTypes.h @@ -624,6 +624,7 @@ enum class CompletionMethods { Tab = 3, Newline = 4, Command = 5, + SingleChoice = 6, }; enum class CharacterSource { diff --git a/ext/scintilla/src/CaseConvert.cxx b/ext/scintilla/src/CaseConvert.cxx index 28a044492..19e381ba7 100644 --- a/ext/scintilla/src/CaseConvert.cxx +++ b/ext/scintilla/src/CaseConvert.cxx @@ -31,7 +31,7 @@ namespace { // Another pattern (pitch==2) is where each lower case letter is preceded by // the upper case form. These are also grouped into ranges. -int symmetricCaseConversionRanges[] = { +constexpr int symmetricCaseConversionRanges[] = { //lower, upper, range length, range pitch //++Autogenerated -- start of section automatically generated //**\(\*\n\) @@ -67,7 +67,7 @@ int symmetricCaseConversionRanges[] = { 8032,8040,8,1, 8560,8544,16,1, 9424,9398,26,1, -11312,11264,47,1, +11312,11264,48,1, 11393,11392,50,2, 11520,4256,38,1, 42561,42560,23,2, @@ -76,10 +76,13 @@ int symmetricCaseConversionRanges[] = { 42803,42802,31,2, 42879,42878,5,2, 42903,42902,10,2, -42933,42932,6,2, +42933,42932,8,2, 65345,65313,26,1, 66600,66560,40,1, 66776,66736,36,1, +66967,66928,11,1, +66979,66940,15,1, +66995,66956,7,1, 68800,68736,51,1, 71872,71840,32,1, 93792,93760,32,1, @@ -91,7 +94,7 @@ int symmetricCaseConversionRanges[] = { // Code points that are symmetric but don't fit into a range of similar characters // are listed here. -int symmetricCaseConversions[] = { +constexpr int symmetricCaseConversions[] = { //lower, upper //++Autogenerated -- start of section automatically generated //**1 \(\*\n\) @@ -241,11 +244,15 @@ int symmetricCaseConversions[] = { 42897,42896, 42899,42898, 42900,42948, -42947,42946, 42952,42951, 42954,42953, +42961,42960, +42967,42966, +42969,42968, 42998,42997, 43859,42931, +67003,66964, +67004,66965, //--Autogenerated -- end of section automatically generated }; @@ -255,7 +262,7 @@ int symmetricCaseConversions[] = { // folding is different to lowering, or (as appropriate) upper(lower(x)) != x or // lower(upper(x)) != x. -const char *complexCaseConversions = +constexpr std::string_view complexCaseConversions = // Original | Folded | Upper | Lower | //++Autogenerated -- start of section automatically generated //**2 \(\*\n\) @@ -570,22 +577,20 @@ const char *complexCaseConversions = //--Autogenerated -- end of section automatically generated ; +// Maximum length of a case conversion result is 6 bytes in UTF-8 +constexpr size_t maxConversionLength = 6; + class CaseConverter : public ICaseConverter { - // Maximum length of a case conversion result is 6 bytes in UTF-8 - enum { maxConversionLength=6 }; struct ConversionString { - char conversion[maxConversionLength+1]; - ConversionString() noexcept : conversion{} { - } + char conversion[maxConversionLength+1]{}; }; // Conversions are initially store in a vector of structs but then decomposed into // parallel arrays as that is about 10% faster to search. struct CharacterConversion { - int character; + int character = 0; ConversionString conversion; - CharacterConversion() noexcept : character(0) { - // Empty case: NUL -> "". - } + // Empty case: NUL -> "". + CharacterConversion() noexcept = default; CharacterConversion(int character_, std::string_view conversion_) noexcept : character(character_) { assert(conversion_.length() <= maxConversionLength); try { @@ -600,6 +605,7 @@ class CaseConverter : public ICaseConverter { return character < other.character; } }; + CaseConversion conversion; typedef std::vector CharacterToConversion; CharacterToConversion characterToConversion; // The parallel arrays @@ -607,7 +613,8 @@ class CaseConverter : public ICaseConverter { std::vector conversions; public: - CaseConverter() = default; + explicit CaseConverter(CaseConversion conversion_) : conversion(conversion_) { + }; // Deleted so CaseConverter objects can not be copied. CaseConverter(const CaseConverter &) = delete; CaseConverter(CaseConverter &&) = delete; @@ -617,8 +624,8 @@ public: bool Initialised() const noexcept { return !characters.empty(); } - void Add(int character, const char *conversion) { - characterToConversion.emplace_back(character, conversion); + void Add(int character, std::string_view conversion_) { + characterToConversion.emplace_back(character, conversion_); } const char *Find(int character) { const std::vector::iterator it = std::lower_bound(characters.begin(), characters.end(), character); @@ -683,32 +690,37 @@ public: // Empty the original calculated data completely CharacterToConversion().swap(characterToConversion); } + void AddSymmetric(int lower, int upper); + void SetupConversions(); }; -CaseConverter caseConvFold; -CaseConverter caseConvUp; -CaseConverter caseConvLow; +CaseConverter caseConvFold(CaseConversion::fold); +CaseConverter caseConvUp(CaseConversion::upper); +CaseConverter caseConvLow(CaseConversion::lower); -void AddSymmetric(CaseConversion conversion, int lower,int upper) { - char lowerUTF8[UTF8MaxBytes+1]; - UTF8FromUTF32Character(lower, lowerUTF8); - char upperUTF8[UTF8MaxBytes+1]; - UTF8FromUTF32Character(upper, upperUTF8); +void CaseConverter::AddSymmetric(int lower, int upper) { + const int character = (conversion == CaseConversion::upper) ? lower : upper; + const int source = (conversion == CaseConversion::upper) ? upper : lower; + char converted[maxConversionLength+1]{}; + UTF8FromUTF32Character(source, converted); + Add(character, converted); +} - switch (conversion) { - case CaseConversion::fold: - caseConvFold.Add(upper, lowerUTF8); - break; - case CaseConversion::upper: - caseConvUp.Add(lower, upperUTF8); - break; - case CaseConversion::lower: - caseConvLow.Add(upper, lowerUTF8); - break; +// Return the next '|' separated field and remove from view. +std::string_view NextField(std::string_view &view) { + const size_t separatorPosition = view.find_first_of('|'); + const std::string_view field = view.substr(0, separatorPosition); + if (separatorPosition == std::string_view::npos) { + // Reached the end so empty the view + view.remove_prefix(view.length()); + } else { + // Remove the '|' from the view as well as the field + view.remove_prefix(separatorPosition + 1); } + return field; } -void SetupConversions(CaseConversion conversion) { +void CaseConverter::SetupConversions() { // First initialize for the symmetric ranges for (size_t i=0; i(originUTF8.data())); + Add(character, converted); } } + FinishedAdding(); +} + +CaseConverter *ConverterForConversion(CaseConversion conversion) { + CaseConverter *pCaseConv = &caseConvFold; switch (conversion) { case CaseConversion::fold: - caseConvFold.FinishedAdding(); + pCaseConv = &caseConvFold; break; case CaseConversion::upper: - caseConvUp.FinishedAdding(); + pCaseConv = &caseConvUp; break; case CaseConversion::lower: - caseConvLow.FinishedAdding(); + default: + pCaseConv = &caseConvLow; break; } -} - -CaseConverter *ConverterForConversion(CaseConversion conversion) noexcept { - switch (conversion) { - case CaseConversion::fold: - return &caseConvFold; - case CaseConversion::upper: - return &caseConvUp; - case CaseConversion::lower: - return &caseConvLow; + if (!pCaseConv->Initialised()) { + pCaseConv->SetupConversions(); } - return nullptr; + return pCaseConv; } } @@ -808,23 +792,16 @@ CaseConverter *ConverterForConversion(CaseConversion conversion) noexcept { namespace Scintilla::Internal { ICaseConverter *ConverterFor(CaseConversion conversion) { - CaseConverter *pCaseConv = ConverterForConversion(conversion); - if (!pCaseConv->Initialised()) - SetupConversions(conversion); - return pCaseConv; + return ConverterForConversion(conversion); } const char *CaseConvert(int character, CaseConversion conversion) { CaseConverter *pCaseConv = ConverterForConversion(conversion); - if (!pCaseConv->Initialised()) - SetupConversions(conversion); return pCaseConv->Find(character); } size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, CaseConversion conversion) { CaseConverter *pCaseConv = ConverterForConversion(conversion); - if (!pCaseConv->Initialised()) - SetupConversions(conversion); return pCaseConv->CaseConvertString(converted, sizeConverted, mixed, lenMixed); } diff --git a/ext/scintilla/src/CharacterCategoryMap.cxx b/ext/scintilla/src/CharacterCategoryMap.cxx index 8c46a6c20..33459292a 100644 --- a/ext/scintilla/src/CharacterCategoryMap.cxx +++ b/ext/scintilla/src/CharacterCategoryMap.cxx @@ -22,7 +22,7 @@ namespace { const int catRanges[] = { //++Autogenerated -- start of section automatically generated -// Created with Python 3.9.4, Unicode 13.0.0 +// Created with Python 3.11.0, Unicode 14.0.0 25, 1046, 1073, @@ -685,8 +685,7 @@ const int catRanges[] = { 49669, 50033, 50074, -50109, -50129, +50097, 50180, 51203, 51236, @@ -751,11 +750,16 @@ const int catRanges[] = { 68605, 68612, 68989, +69124, +69908, +69924, +70141, +70170, +70237, +70405, 70660, -71357, -71364, -71965, -72293, +71971, +72005, 72794, 72805, 73830, @@ -988,6 +992,7 @@ const int catRanges[] = { 99645, 99652, 100189, +100229, 100260, 100293, 100390, @@ -1000,6 +1005,8 @@ const int catRanges[] = { 101117, 101124, 101245, +101284, +101341, 101380, 101445, 101533, @@ -1036,7 +1043,7 @@ const int catRanges[] = { 104925, 105126, 105213, -105412, +105380, 105469, 105476, 105541, @@ -1289,12 +1296,12 @@ const int catRanges[] = { 187940, 188221, 188420, -188861, -188868, 188997, -189117, -189444, +189094, +189149, +189412, 190021, +190086, 190129, 190205, 190468, @@ -1330,7 +1337,7 @@ const int catRanges[] = { 196849, 196965, 197082, -197117, +197093, 197128, 197469, 197636, @@ -1405,7 +1412,7 @@ const int catRanges[] = { 218629, 219079, 219109, -219197, +219645, 221189, 221318, 221348, @@ -1418,13 +1425,14 @@ const int catRanges[] = { 223301, 223334, 223396, -223645, +223677, 223752, 224081, 224309, 224613, 224917, -225213, +225201, +225277, 225285, 225350, 225380, @@ -1489,8 +1497,6 @@ const int catRanges[] = { 241441, 242531, 243717, -245597, -245605, 245760, 245793, 245824, @@ -1852,7 +1858,7 @@ const int catRanges[] = { 266755, 267197, 267283, -268317, +268349, 268805, 269223, 269349, @@ -2032,9 +2038,7 @@ const int catRanges[] = { 357085, 357109, 360448, -361981, 361985, -363517, 363520, 363553, 363584, @@ -2235,7 +2239,16 @@ const int catRanges[] = { 378993, 379413, 379473, -379517, +379565, +379598, +379629, +379662, +379693, +379726, +379757, +379790, +379820, +379869, 380949, 381789, 381813, @@ -2323,8 +2336,6 @@ const int catRanges[] = { 425988, 636949, 638980, -1310653, -1310724, 1311395, 1311428, 1348029, @@ -2568,7 +2579,8 @@ const int catRanges[] = { 1374113, 1374144, 1374177, -1374237, +1374208, +1374241, 1374272, 1374305, 1374336, @@ -2576,6 +2588,18 @@ const int catRanges[] = { 1374496, 1374529, 1374589, +1374720, +1374753, +1374813, +1374817, +1374877, +1374881, +1374912, +1374945, +1374976, +1375009, +1375069, +1375811, 1375904, 1375937, 1375972, @@ -2761,19 +2785,20 @@ const int catRanges[] = { 2058429, 2058436, 2061908, -2062429, +2062461, 2062948, 2074574, 2074605, -2074653, +2074645, 2075140, 2077213, 2077252, 2079005, +2079221, +2079261, 2080260, 2080659, 2080693, -2080733, 2080773, 2081297, 2081517, @@ -2963,13 +2988,34 @@ const int catRanges[] = { 2139652, 2141341, 2141681, -2141725, +2141696, +2142077, +2142080, +2142589, +2142592, +2142845, +2142848, +2142941, +2142945, +2143325, +2143329, +2143837, +2143841, +2144093, +2144097, +2144189, 2146308, 2156285, 2156548, 2157277, 2157572, 2157853, +2158595, +2158813, +2158819, +2160189, +2160195, +2160509, 2162692, 2162909, 2162948, @@ -3089,6 +3135,10 @@ const int catRanges[] = { 2222634, 2222769, 2222941, +2223620, +2224197, +2224337, +2224477, 2225668, 2226346, 2226589, @@ -3103,7 +3153,11 @@ const int catRanges[] = { 2230749, 2230858, 2231496, -2231837, +2231813, +2231844, +2231909, +2231972, +2232029, 2232293, 2232390, 2232420, @@ -3114,7 +3168,8 @@ const int catRanges[] = { 2234225, 2234298, 2234321, -2234461, +2234437, +2234493, 2234810, 2234845, 2234884, @@ -3290,7 +3345,8 @@ const int catRanges[] = { 2283206, 2283237, 2283268, -2283325, +2283313, +2283357, 2283528, 2283869, 2285572, @@ -3305,7 +3361,8 @@ const int catRanges[] = { 2287434, 2287505, 2287605, -2287645, +2287620, +2287869, 2293764, 2295174, 2295269, @@ -3379,7 +3436,7 @@ const int catRanges[] = { 2315172, 2315217, 2315389, -2316292, +2315780, 2318141, 2326532, 2326845, @@ -3463,6 +3520,9 @@ const int catRanges[] = { 2395837, 2396164, 2402461, +2486788, +2489905, +2489981, 2490372, 2524669, 2524698, @@ -3476,7 +3536,10 @@ const int catRanges[] = { 2968584, 2968925, 2969041, -2969117, +2969092, +2971645, +2971656, +2971997, 2972164, 2973149, 2973189, @@ -3525,8 +3588,14 @@ const int catRanges[] = { 3250909, 3252228, 3252541, +3538435, +3538589, +3538595, +3538845, +3538851, +3538941, 3538948, -3548157, +3548285, 3549700, 3549821, 3550340, @@ -3546,6 +3615,12 @@ const int catRanges[] = { 3642353, 3642394, 3642525, +3792901, +3794397, +3794437, +3795197, +3795477, +3799197, 3801109, 3808989, 3809301, @@ -3562,7 +3637,7 @@ const int catRanges[] = { 3813781, 3814725, 3814869, -3816765, +3816829, 3817493, 3819589, 3819701, @@ -3678,6 +3753,10 @@ const int catRanges[] = { 3888157, 3888165, 3888669, +3923969, +3924292, +3924321, +3924989, 3932165, 3932413, 3932421, @@ -3698,12 +3777,23 @@ const int catRanges[] = { 3942852, 3942901, 3942941, +3953156, +3954117, +3954173, 3954692, 3956101, 3956232, 3956573, 3956723, 3956765, +3996676, +3996925, +3996932, +3997085, +3997092, +3997181, +3997188, +3997693, 3997700, 4004029, 4004074, @@ -3825,7 +3915,7 @@ const int catRanges[] = { 4095860, 4096021, 4119325, -4119573, +4119477, 4119997, 4120085, 4120509, @@ -3835,6 +3925,8 @@ const int catRanges[] = { 4127549, 4127765, 4128157, +4128277, +4128317, 4128789, 4129181, 4129301, @@ -3848,27 +3940,27 @@ const int catRanges[] = { 4134421, 4134493, 4136981, -4140861, -4140885, -4143517, -4143541, 4147869, 4148245, 4148701, 4148757, 4148925, 4149013, -4149117, +4149181, 4149269, 4149501, 4149781, -4150589, +4150717, 4150805, -4151037, +4151165, 4151317, -4151421, +4151517, 4151829, -4152061, +4152157, +4152341, +4152605, +4152853, +4153085, 4153365, 4158077, 4158101, @@ -3876,9 +3968,9 @@ const int catRanges[] = { 4161032, 4161373, 4194308, -5561309, +5561373, 5562372, -5695165, +5695293, 5695492, 5702621, 5702660, diff --git a/ext/scintilla/src/Document.cxx b/ext/scintilla/src/Document.cxx index 0ea6007ce..0b8dfdfd4 100644 --- a/ext/scintilla/src/Document.cxx +++ b/ext/scintilla/src/Document.cxx @@ -56,7 +56,7 @@ LexInterface::LexInterface(Document *pdoc_) noexcept : pdoc(pdoc_), performingSt LexInterface::~LexInterface() noexcept = default; -void LexInterface::SetInstance(ILexer5 *instance_) { +void LexInterface::SetInstance(ILexer5 *instance_) noexcept { instance.reset(instance_); } @@ -125,6 +125,18 @@ size_t ActionDuration::ActionsInAllowedTime(double secondsAllowed) const noexcep return std::lround(secondsAllowed / Duration()); } +CharacterExtracted::CharacterExtracted(const unsigned char *charBytes, size_t widthCharBytes) noexcept { + const int utf8status = UTF8Classify(charBytes, widthCharBytes); + if (utf8status & UTF8MaskInvalid) { + // Treat as invalid and use up just one byte + character = unicodeReplacementChar; + widthBytes = 1; + } else { + character = UnicodeFromUTF8(charBytes); + widthBytes = utf8status & UTF8MaskWidth; + } +} + Document::Document(DocumentOption options) : cb(!FlagSet(options, DocumentOption::StylesNone), FlagSet(options, DocumentOption::TextLarge)), durationStyleOneByte(0.000001, 0.0000001, 0.00001) { @@ -917,7 +929,7 @@ bool Document::NextCharacter(Sci::Position &pos, int moveDir) const noexcept { } } -Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) const noexcept { +CharacterExtracted Document::CharacterAfter(Sci::Position position) const noexcept { if (position >= LengthNoExcept()) { return CharacterExtracted(unicodeReplacementChar, 0); } @@ -931,13 +943,7 @@ Document::CharacterExtracted Document::CharacterAfter(Sci::Position position) co unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; for (int b = 1; b= 0) && (line < LinesTotal())) { @@ -1757,7 +1772,10 @@ bool Document::IsWhiteLine(Sci::Line line) const { Sci::Position Document::ParaUp(Sci::Position pos) const { Sci::Line line = SciLineFromPosition(pos); - line--; + const Sci::Position start = LineStart(line); + if (pos == start) { + line--; + } while (line >= 0 && IsWhiteLine(line)) { // skip empty lines line--; } @@ -2033,7 +2051,7 @@ void Document::SetCaseFolder(std::unique_ptr pcf_) noexcept { pcf = std::move(pcf_); } -Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position) const noexcept { +CharacterExtracted Document::ExtractCharacter(Sci::Position position) const noexcept { const unsigned char leadByte = cb.UCharAt(position); if (UTF8IsAscii(leadByte)) { // Common case: ASCII character @@ -2043,13 +2061,7 @@ Document::CharacterExtracted Document::ExtractCharacter(Sci::Position position) unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; for (int b=1; bFold(&searchThing[0], searchThing.size(), search, lengthFind); while (forward ? (pos < endPos) : (pos >= endPos)) { - int widthFirstCharacter = 0; + int widthFirstCharacter = 1; Sci::Position posIndexDocument = pos; size_t indexSearch = 0; bool characterMatches = true; - for (;;) { + while (indexSearch < lenSearch) { const unsigned char leadByte = cbView.CharAt(posIndexDocument); - char bytes[UTF8MaxBytes + 1]; int widthChar = 1; - if (!UTF8IsAscii(leadByte)) { - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - bytes[0] = leadByte; - for (int b=1; b(bytes), widthCharBytes) & UTF8MaskWidth; - } - if (!widthFirstCharacter) { - widthFirstCharacter = widthChar; - } - if ((posIndexDocument + widthChar) > limitPos) { - break; - } size_t lenFlat = 1; - if (widthChar == 1) { + if (UTF8IsAscii(leadByte)) { + if ((posIndexDocument + 1) > limitPos) { + break; + } characterMatches = searchThing[indexSearch] == MakeLowerCase(leadByte); } else { + char bytes[UTF8MaxBytes]{ static_cast(leadByte) }; + const int widthCharBytes = UTF8BytesOfLead[leadByte]; + for (int b = 1; b < widthCharBytes; b++) { + bytes[b] = cbView.CharAt(posIndexDocument + b); + } + widthChar = UTF8Classify(reinterpret_cast(bytes), widthCharBytes) & UTF8MaskWidth; + if (!indexSearch) { // First character + widthFirstCharacter = widthChar; + } + if ((posIndexDocument + widthChar) > limitPos) { + break; + } char folded[UTF8MaxBytes * maxFoldingExpansion + 1]; lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); // memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing @@ -2211,9 +2223,6 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con } posIndexDocument += widthChar; indexSearch += lenFlat; - if (indexSearch >= lenSearch) { - break; - } } if (characterMatches && (indexSearch == lenSearch)) { if (MatchesWordOptions(word, wordStart, pos, posIndexDocument - pos)) { @@ -2253,9 +2262,10 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con if (widthChar == 1) { characterMatches = searchThing[indexSearch] == MakeLowerCase(leadByte); } else { - char bytes[maxBytesCharacter + 1]; - bytes[0] = leadByte; - bytes[1] = cbView.CharAt(pos + indexDocument + 1); + const char bytes[maxBytesCharacter + 1] { + static_cast(leadByte), + cbView.CharAt(pos + indexDocument + 1) + }; char folded[maxBytesCharacter * maxFoldingExpansion + 1]; lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar); // memcmp may examine lenFlat bytes in both arguments so assert it doesn't read past end of searchThing @@ -3036,7 +3046,7 @@ public: } private: void ReadCharacter() noexcept { - const Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); + const CharacterExtracted charExtracted = doc->ExtractCharacter(position); lenBytes = charExtracted.widthBytes; if (charExtracted.character == unicodeReplacementChar) { lenCharacters = 1; @@ -3065,7 +3075,7 @@ public: doc(doc_), position(position_) { } wchar_t operator*() const noexcept { - const Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); + const CharacterExtracted charExtracted = doc->ExtractCharacter(position); return charExtracted.character; } UTF8Iterator &operator++() noexcept { diff --git a/ext/scintilla/src/Document.h b/ext/scintilla/src/Document.h index b1be6c88a..a70c1696d 100644 --- a/ext/scintilla/src/Document.h +++ b/ext/scintilla/src/Document.h @@ -46,6 +46,10 @@ public: return (start != Sci::invalidPosition) && (end != Sci::invalidPosition); } + [[nodiscard]] bool Empty() const noexcept { + return start == end; + } + Sci::Position First() const noexcept { return (start <= end) ? start : end; } @@ -195,7 +199,7 @@ public: LexInterface &operator=(const LexInterface &) = delete; LexInterface &operator=(LexInterface &&) = delete; virtual ~LexInterface() noexcept; - void SetInstance(ILexer5 *instance_); + void SetInstance(ILexer5 *instance_) noexcept; void Colourise(Sci::Position start, Sci::Position end); virtual Scintilla::LineEndType LineEndTypesSupported(); bool UseContainerLexing() const noexcept; @@ -227,6 +231,29 @@ public: }; /** + * A whole character (code point) with a value and width in bytes. + * For UTF-8, the value is the code point value. + * For DBCS, its jamming the lead and trail bytes together. + * For 8 bit encodings, is just the byte value. + */ +struct CharacterExtracted { + unsigned int character; + unsigned int widthBytes; + + CharacterExtracted(unsigned int character_, unsigned int widthBytes_) noexcept : + character(character_), widthBytes(widthBytes_) { + } + + // For UTF-8: + CharacterExtracted(const unsigned char *charBytes, size_t widthCharBytes) noexcept; + + // For DBCS characters turn 2 bytes into an int + static CharacterExtracted DBCS(unsigned char lead, unsigned char trail) noexcept { + return CharacterExtracted((lead << 8) | trail, 2); + } +}; + +/** */ class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader { @@ -276,18 +303,6 @@ private: public: - struct CharacterExtracted { - unsigned int character; - unsigned int widthBytes; - CharacterExtracted(unsigned int character_, unsigned int widthBytes_) noexcept : - character(character_), widthBytes(widthBytes_) { - } - // For DBCS characters turn 2 bytes into an int - static CharacterExtracted DBCS(unsigned char lead, unsigned char trail) noexcept { - return CharacterExtracted((lead << 8) | trail, 2); - } - }; - Scintilla::EndOfLine eolMode; /// Can also be SC_CP_UTF8 to enable UTF-8 mode int dbcsCodePage; @@ -341,8 +356,8 @@ public: Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const noexcept; Sci::Position NextPosition(Sci::Position pos, int moveDir) const noexcept; bool NextCharacter(Sci::Position &pos, int moveDir) const noexcept; // Returns true if pos changed - Document::CharacterExtracted CharacterAfter(Sci::Position position) const noexcept; - Document::CharacterExtracted CharacterBefore(Sci::Position position) const noexcept; + CharacterExtracted CharacterAfter(Sci::Position position) const noexcept; + CharacterExtracted CharacterBefore(Sci::Position position) const noexcept; Sci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const override; Sci::Position GetRelativePositionUTF16(Sci::Position positionStart, Sci::Position characterOffset) const noexcept; int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const override; @@ -358,8 +373,10 @@ public: // Gateways to modifying document void ModifiedAt(Sci::Position pos) noexcept; void CheckReadOnly(); + void TrimReplacement(std::string_view &text, Range &range) const noexcept; bool DeleteChars(Sci::Position pos, Sci::Position len); Sci::Position InsertString(Sci::Position position, const char *s, Sci::Position insertLength); + Sci::Position InsertString(Sci::Position position, std::string_view sv); void ChangeInsertion(const char *s, Sci::Position length); int SCI_METHOD AddData(const char *data, Sci_Position length) override; void * SCI_METHOD ConvertToDocument() override; @@ -396,7 +413,7 @@ public: int SCI_METHOD GetLineIndentation(Sci_Position line) override; Sci::Position SetLineIndentation(Sci::Line line, Sci::Position indent); Sci::Position GetLineIndentPosition(Sci::Line line) const; - Sci::Position GetColumn(Sci::Position pos); + Sci::Position GetColumn(Sci::Position pos) const; Sci::Position CountCharacters(Sci::Position startPos, Sci::Position endPos) const noexcept; Sci::Position CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept; Sci::Position FindColumn(Sci::Line line, Sci::Position column); @@ -416,6 +433,7 @@ public: cb.GetCharRange(buffer, position, lengthRetrieve); } char SCI_METHOD StyleAt(Sci_Position position) const override { return cb.StyleAt(position); } + char StyleAtNoExcept(Sci_Position position) const noexcept { return cb.StyleAt(position); } int StyleIndexAt(Sci_Position position) const noexcept { return static_cast(cb.StyleAt(position)); } void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const { cb.GetStyleRange(buffer, position, lengthRetrieve); diff --git a/ext/scintilla/src/EditView.cxx b/ext/scintilla/src/EditView.cxx index 329c63d38..cdf3bb4bf 100644 --- a/ext/scintilla/src/EditView.cxx +++ b/ext/scintilla/src/EditView.cxx @@ -65,7 +65,6 @@ #include "MarginView.h" #include "EditView.h" #include "ElapsedPeriod.h" -#include "Editor.h" using namespace Scintilla; using namespace Scintilla::Internal; @@ -200,7 +199,6 @@ EditView::EditView() { tabArrowHeight = 4; customDrawTabArrow = nullptr; customDrawWrapMarker = nullptr; - editor = nullptr; } EditView::~EditView() = default; @@ -1573,21 +1571,34 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c // Draw any box or stadium shape if (FlagSet(phase, DrawPhase::indicatorsBack)) { - if (vsDraw.eolAnnotationVisible >= EOLAnnotationVisible::Boxed) { - PRectangle rcBox = rcSegment; - rcBox.left = std::round(rcSegment.left); - rcBox.right = std::round(rcSegment.right); - if (vsDraw.eolAnnotationVisible == EOLAnnotationVisible::Boxed) { - surface->RectangleFrame(rcBox, Stroke(textFore)); + const PRectangle rcBox = PixelAlign(rcSegment, 1); + + switch (vsDraw.eolAnnotationVisible) { + case EOLAnnotationVisible::Standard: + if (phasesDraw != PhasesDraw::One) { + surface->FillRectangle(rcBox, textBack); + } + break; + + case EOLAnnotationVisible::Boxed: + if (phasesDraw == PhasesDraw::One) { + // Draw a rectangular outline around the text + surface->RectangleFrame(rcBox, textFore); } else { - if (phasesDraw == PhasesDraw::One) { - // Draw an outline around the text - surface->Stadium(rcBox, FillStroke(ColourRGBA(textBack, 0), textFore, 1.0), ends); - } else { - // Draw with a fill to fill the edges of the shape. - surface->Stadium(rcBox, FillStroke(textBack, textFore, 1.0), ends); - } + // Draw with a fill to fill the edges of the rectangle. + surface->RectangleDraw(rcBox, FillStroke(textBack, textFore)); } + break; + + default: + if (phasesDraw == PhasesDraw::One) { + // Draw an outline around the text + surface->Stadium(rcBox, FillStroke(ColourRGBA(textBack, 0), textFore), ends); + } else { + // Draw with a fill to fill the edges of the shape. + surface->Stadium(rcBox, FillStroke(textBack, textFore), ends); + } + break; } } @@ -2387,15 +2398,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl } // See if something overrides the line background colour. - std::optional background = vsDraw.Background(model.GetMark(line), model.caret.active, ll->containsCaret); - SCNotification scn = { 0 }; - scn.nmhdr.code = SCN_GETBKCOLOR; - scn.line = line; - scn.lParam = -1; - if (editor) - ((Editor*)editor)->NotifyParent(&scn); - if (scn.lParam != -1) - background = ColourRGBA::FromRGB(static_cast(scn.lParam)); + const std::optional background = vsDraw.Background(model.GetMark(line), model.caret.active, ll->containsCaret); const Sci::Position posLineStart = model.pdoc->LineStart(line); diff --git a/ext/scintilla/src/EditView.h b/ext/scintilla/src/EditView.h index dd6c715e0..aa5de4226 100644 --- a/ext/scintilla/src/EditView.h +++ b/ext/scintilla/src/EditView.h @@ -78,7 +78,6 @@ public: std::unique_ptr pixmapLine; std::unique_ptr pixmapIndentGuide; std::unique_ptr pixmapIndentGuideHighlight; - void *editor; LineLayoutCache llc; std::unique_ptr posCache; diff --git a/ext/scintilla/src/Editor.cxx b/ext/scintilla/src/Editor.cxx index b45f8dfa6..1b337a9d0 100644 --- a/ext/scintilla/src/Editor.cxx +++ b/ext/scintilla/src/Editor.cxx @@ -119,7 +119,6 @@ static constexpr bool IsAllSpacesOrTabs(std::string_view sv) noexcept { } Editor::Editor() : durationWrapOneByte(0.000001, 0.00000001, 0.00001) { - view.editor = this; ctrlID = 0; stylesValid = false; @@ -5697,15 +5696,27 @@ Sci::Position Editor::GetTag(char *tagValue, int tagNumber) { return length; } -Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci::Position length) { +Sci::Position Editor::ReplaceTarget(ReplaceType replaceType, std::string_view text) { UndoGroup ug(pdoc); - if (length == -1) - length = strlen(text); - if (replacePatterns) { - text = pdoc->SubstituteByPosition(text, &length); - if (!text) { + if (replaceType == ReplaceType::patterns) { + Sci::Position length = text.length(); + const char *p = pdoc->SubstituteByPosition(text.data(), &length); + if (!p) { return 0; } + text = std::string_view(p, length); + } + + if (replaceType == ReplaceType::minimal) { + // Check for prefix and suffix and reduce text and target to match. + // This is performed with Range which doesn't support virtual space. + Range range(targetRange.start.Position(), targetRange.end.Position()); + pdoc->TrimReplacement(text, range); + // Re-apply virtual space to start if start position didn't change. + // Don't bother with end as its virtual space is not used + const SelectionPosition start(range.start == targetRange.start.Position() ? + targetRange.start : SelectionPosition(range.start)); + targetRange = SelectionSegment(start, SelectionPosition(range.end)); } // Remove the text inside the range @@ -5719,9 +5730,9 @@ Sci::Position Editor::ReplaceTarget(bool replacePatterns, const char *text, Sci: targetRange.end = targetRange.start; // Insert the new text - const Sci::Position lengthInserted = pdoc->InsertString(targetRange.start.Position(), text, length); + const Sci::Position lengthInserted = pdoc->InsertString(targetRange.start.Position(), text); targetRange.end.SetPosition(targetRange.start.Position() + lengthInserted); - return length; + return text.length(); } bool Editor::IsUnicodeMode() const noexcept { @@ -5784,6 +5795,27 @@ 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->StyleAtNoExcept(iChar); + } + buffer[iPlace] = '\0'; + buffer[iPlace + 1] = '\0'; + return iPlace; +} + +Sci::Position Editor::GetTextRange(char *buffer, Sci::Position cpMin, Sci::Position cpMax) const { + const Sci::Position cpEnd = (cpMax == -1) ? pdoc->Length() : cpMax; + PLATFORM_ASSERT(cpEnd <= pdoc->Length()); + const Sci::Position len = cpEnd - cpMin; // No -1 as cpMin and cpMax are referring to inter character positions + pdoc->GetCharRange(buffer, cpMin, len); + // Spec says copied text is terminated with a NUL + buffer[len] = '\0'; + return len; // Not including NUL +} + bool Editor::ValidMargin(uptr_t wParam) const noexcept { return wParam < vs.ms.size(); } @@ -5840,7 +5872,7 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) { if (!(classified & UTF8MaskInvalid)) { // valid UTF-8 int len = classified & UTF8MaskWidth; - while (len--) + for (int i=0; i(PtrFromSPtr(lParam)); - Sci::Position cpMax = static_cast(tr->chrg.cpMax); - if (cpMax == -1) - cpMax = pdoc->Length(); - PLATFORM_ASSERT(cpMax <= pdoc->Length()); - Sci::Position len = cpMax - tr->chrg.cpMin; // No -1 as cpMin and cpMax are referring to inter character positions - 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::GetTextRangeFull: { - if (lParam == 0) - return 0; - TextRangeFull *tr = static_cast(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::GetTextRange: + if (TextRange *tr = static_cast(PtrFromSPtr(lParam))) { + return GetTextRange(tr->lpstrText, tr->chrg.cpMin, tr->chrg.cpMax); + } + return 0; + + case Message::GetTextRangeFull: + if (TextRangeFull *tr = static_cast(PtrFromSPtr(lParam))) { + return GetTextRange(tr->lpstrText, tr->chrg.cpMin, tr->chrg.cpMax); } + return 0; case Message::HideSelection: vs.selection.visible = wParam == 0; @@ -6589,19 +6606,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(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(PtrFromSPtr(lParam))) { + return GetStyledText(tr->lpstrText, tr->chrg.cpMin, tr->chrg.cpMax); + } + return 0; + + case Message::GetStyledTextFull: + if (TextRangeFull *tr = static_cast(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/ext/scintilla/src/Editor.h b/ext/scintilla/src/Editor.h index f516f6506..58244d4e4 100644 --- a/ext/scintilla/src/Editor.h +++ b/ext/scintilla/src/Editor.h @@ -7,7 +7,6 @@ #ifndef EDITOR_H #define EDITOR_H -#include "Scintilla.h" namespace Scintilla::Internal { @@ -582,7 +581,8 @@ protected: // ScintillaBase subclass needs access to much of Editor void FoldAll(Scintilla::FoldAction action); Sci::Position GetTag(char *tagValue, int tagNumber); - Sci::Position ReplaceTarget(bool replacePatterns, const char *text, Sci::Position length=-1); + enum class ReplaceType {basic, patterns, minimal}; + Sci::Position ReplaceTarget(ReplaceType replaceType, std::string_view text); bool PositionIsHotspot(Sci::Position position) const noexcept; bool PointIsHotspot(Point pt); @@ -599,6 +599,8 @@ 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; + Sci::Position GetTextRange(char *buffer, Sci::Position cpMin, Sci::Position cpMax) const; 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; @@ -624,6 +626,12 @@ protected: // ScintillaBase subclass needs access to much of Editor static unsigned char *UCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept { return static_cast(PtrFromSPtr(lParam)); } + static std::string_view ViewFromParams(Scintilla::sptr_t lParam, Scintilla::uptr_t wParam) noexcept { + if (SPtrFromUPtr(wParam) == -1) { + return std::string_view(CharPtrFromSPtr(lParam)); + } + return std::string_view(CharPtrFromSPtr(lParam), wParam); + } static void *PtrFromUPtr(Scintilla::uptr_t wParam) noexcept { return reinterpret_cast(wParam); } @@ -670,7 +678,6 @@ protected: // ScintillaBase subclass needs access to much of Editor public: ~Editor() override; - virtual void NotifyParent(SCNotification *scn) = 0; // Public so the COM thunks can access it. bool IsUnicodeMode() const noexcept; // Public so scintilla_send_message can use it. diff --git a/ext/scintilla/src/ScintillaBase.cxx b/ext/scintilla/src/ScintillaBase.cxx index aea9a5588..30c1c4747 100644 --- a/ext/scintilla/src/ScintillaBase.cxx +++ b/ext/scintilla/src/ScintillaBase.cxx @@ -211,11 +211,11 @@ void ScintillaBase::ListNotify(ListBoxEvent *plbe) { } } -void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, const char *text, Sci::Position textLen) { +void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, std::string_view text) { UndoGroup ug(pdoc); if (multiAutoCMode == MultiAutoComplete::Once) { pdoc->DeleteChars(startPos, removeLen); - const Sci::Position lengthInserted = pdoc->InsertString(startPos, text, textLen); + const Sci::Position lengthInserted = pdoc->InsertString(startPos, text); SetEmptySelection(startPos + lengthInserted); } else { // MultiAutoComplete::Each @@ -228,7 +228,7 @@ void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, Sci::Position rem positionInsert -= removeLen; pdoc->DeleteChars(positionInsert, removeLen); } - const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, text, textLen); + const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, text); if (lengthInserted > 0) { sel.Range(r).caret.SetPosition(positionInsert + lengthInserted); sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted); @@ -245,15 +245,20 @@ void ScintillaBase::AutoCompleteStart(Sci::Position lenEntered, const char *list if (ac.chooseSingle && (listType == 0)) { if (list && !strchr(list, ac.GetSeparator())) { - const char *typeSep = strchr(list, ac.GetTypesep()); - const Sci::Position lenInsert = typeSep ? - (typeSep-list) : strlen(list); + // list contains just one item so choose it + const std::string_view item(list); + const std::string_view choice = item.substr(0, item.find_first_of(ac.GetTypesep())); if (ac.ignoreCase) { // May need to convert the case before invocation, so remove lenEntered characters - AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert); + AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, choice); } else { - AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered); + AutoCompleteInsert(sel.MainCaret(), 0, choice.substr(lenEntered)); } + const Sci::Position firstPos = sel.MainCaret() - lenEntered; + // Construct a string with a NUL at end as that is expected by applications + const std::string selected(choice); + AutoCompleteNotifyCompleted('\0', CompletionMethods::SingleChoice, firstPos, selected.c_str()); + ac.Cancel(); return; } @@ -395,6 +400,20 @@ void ScintillaBase::AutoCompleteCharacterDeleted() { NotifyParent(scn); } +void ScintillaBase::AutoCompleteNotifyCompleted(char ch, CompletionMethods completionMethod, Sci::Position firstPos, const char *text) { + NotificationData scn = {}; + scn.nmhdr.code = Notification::AutoCCompleted; + scn.message = static_cast(0); + scn.ch = ch; + scn.listCompletionMethod = completionMethod; + scn.wParam = listType; + scn.listType = listType; + scn.position = firstPos; + scn.lParam = firstPos; + scn.text = text; + NotifyParent(scn); +} + void ScintillaBase::AutoCompleteCompleted(char ch, CompletionMethods completionMethod) { const int item = ac.GetSelection(); if (item == -1) { @@ -430,12 +449,10 @@ void ScintillaBase::AutoCompleteCompleted(char ch, CompletionMethods completionM endPos = pdoc->ExtendWordSelect(endPos, 1, true); if (endPos < firstPos) return; - AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), selected.length()); + AutoCompleteInsert(firstPos, endPos - firstPos, selected); SetLastXChosen(); - scn.nmhdr.code = Notification::AutoCCompleted; - NotifyParent(scn); - + AutoCompleteNotifyCompleted(ch, completionMethod, firstPos, selected.c_str()); } int ScintillaBase::AutoCompleteGetCurrent() const { diff --git a/ext/scintilla/src/ScintillaBase.h b/ext/scintilla/src/ScintillaBase.h index 87198da76..d110bc2bb 100644 --- a/ext/scintilla/src/ScintillaBase.h +++ b/ext/scintilla/src/ScintillaBase.h @@ -57,7 +57,7 @@ protected: void CancelModes() override; int KeyCommand(Scintilla::Message iMessage) override; - void AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, const char *text, Sci::Position textLen); + void AutoCompleteInsert(Sci::Position startPos, Sci::Position removeLen, std::string_view text); void AutoCompleteStart(Sci::Position lenEntered, const char *list); void AutoCompleteCancel(); void AutoCompleteMove(int delta); @@ -65,6 +65,7 @@ protected: int AutoCompleteGetCurrentText(char *buffer) const; void AutoCompleteCharacterAdded(char ch); void AutoCompleteCharacterDeleted(); + void AutoCompleteNotifyCompleted(char ch, CompletionMethods completionMethod, Sci::Position firstPos, const char *text); void AutoCompleteCompleted(char ch, Scintilla::CompletionMethods completionMethod); void AutoCompleteMoveToCurrentWord(); void AutoCompleteSelection(); diff --git a/ext/scintilla/version.txt b/ext/scintilla/version.txt index 2af3c2210..adfa0268e 100644 --- a/ext/scintilla/version.txt +++ b/ext/scintilla/version.txt @@ -1 +1 @@ -531 +532 diff --git a/ext/scintilla/win32/PlatWin.cxx b/ext/scintilla/win32/PlatWin.cxx index 7dc450c70..22ce18003 100644 --- a/ext/scintilla/win32/PlatWin.cxx +++ b/ext/scintilla/win32/PlatWin.cxx @@ -36,6 +36,7 @@ #include #include #include +#include #if !defined(DISABLE_D2D) #define USE_D2D 1 @@ -157,11 +158,24 @@ GetSystemMetricsForDpiSig fnGetSystemMetricsForDpi = nullptr; using AdjustWindowRectExForDpiSig = BOOL(WINAPI *)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi); AdjustWindowRectExForDpiSig fnAdjustWindowRectExForDpi = nullptr; +using AreDpiAwarenessContextsEqualSig = BOOL(WINAPI *)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT); +AreDpiAwarenessContextsEqualSig fnAreDpiAwarenessContextsEqual = nullptr; + +using GetWindowDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)(HWND); +GetWindowDpiAwarenessContextSig fnGetWindowDpiAwarenessContext = nullptr; + +using GetScaleFactorForMonitorSig = HRESULT(WINAPI *)(HMONITOR, DEVICE_SCALE_FACTOR *); +GetScaleFactorForMonitorSig fnGetScaleFactorForMonitor = nullptr; + +using SetThreadDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)(DPI_AWARENESS_CONTEXT); +SetThreadDpiAwarenessContextSig fnSetThreadDpiAwarenessContext = nullptr; + void LoadDpiForWindow() noexcept { HMODULE user32 = ::GetModuleHandleW(L"user32.dll"); fnGetDpiForWindow = DLLFunction(user32, "GetDpiForWindow"); fnGetSystemMetricsForDpi = DLLFunction(user32, "GetSystemMetricsForDpi"); fnAdjustWindowRectExForDpi = DLLFunction(user32, "AdjustWindowRectExForDpi"); + fnSetThreadDpiAwarenessContext = DLLFunction(user32, "SetThreadDpiAwarenessContext"); using GetDpiForSystemSig = UINT(WINAPI *)(void); GetDpiForSystemSig fnGetDpiForSystem = DLLFunction(user32, "GetDpiForSystem"); @@ -173,11 +187,13 @@ void LoadDpiForWindow() noexcept { ::DeleteDC(hdcMeasure); } - if (!fnGetDpiForWindow) { - hDLLShcore = ::LoadLibraryExW(L"shcore.dll", {}, LOAD_LIBRARY_SEARCH_SYSTEM32); - if (hDLLShcore) { - fnGetDpiForMonitor = DLLFunction(hDLLShcore, "GetDpiForMonitor"); - } + fnGetWindowDpiAwarenessContext = DLLFunction(user32, "GetWindowDpiAwarenessContext"); + fnAreDpiAwarenessContextsEqual = DLLFunction(user32, "AreDpiAwarenessContextsEqual"); + + hDLLShcore = ::LoadLibraryExW(L"shcore.dll", {}, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (hDLLShcore) { + fnGetScaleFactorForMonitor = DLLFunction(hDLLShcore, "GetScaleFactorForMonitor"); + fnGetDpiForMonitor = DLLFunction(hDLLShcore, "GetDpiForMonitor"); } } @@ -358,6 +374,39 @@ struct FontDirectWrite : public FontWin { } +HMONITOR MonitorFromWindowHandleScaling(HWND hWnd) noexcept { + constexpr DWORD monitorFlags = MONITOR_DEFAULTTONEAREST; + + if (!fnSetThreadDpiAwarenessContext) { + return ::MonitorFromWindow(hWnd, monitorFlags); + } + + // Temporarily switching to PerMonitorV2 to retrieve correct monitor via MonitorFromRect() in case of active GDI scaling. + const DPI_AWARENESS_CONTEXT oldContext = fnSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + PLATFORM_ASSERT(oldContext != nullptr); + + RECT rect; + ::GetWindowRect(hWnd, &rect); + const HMONITOR monitor = ::MonitorFromRect(&rect, monitorFlags); + + fnSetThreadDpiAwarenessContext(oldContext); + return monitor; +} + +int GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept { + if (fnAreDpiAwarenessContextsEqual) { + PLATFORM_ASSERT(fnGetWindowDpiAwarenessContext && fnGetScaleFactorForMonitor); + if (fnAreDpiAwarenessContextsEqual(DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, fnGetWindowDpiAwarenessContext(hWnd))) { + const HWND hRootWnd = ::GetAncestor(hWnd, GA_ROOT); // Scale factor applies to entire (root) window. + const HMONITOR hMonitor = MonitorFromWindowHandleScaling(hRootWnd); + DEVICE_SCALE_FACTOR deviceScaleFactor; + if (S_OK == fnGetScaleFactorForMonitor(hMonitor, &deviceScaleFactor)) + return (static_cast(deviceScaleFactor) + 99) / 100; // increase to first integral multiple of 1 + } + } + return 1; +} + std::shared_ptr Font::Allocate(const FontParameters &fp) { #if defined(USE_D2D) if (fp.technology != Technology::Default) { @@ -1287,11 +1336,13 @@ class SurfaceD2D : public Surface, public ISetRenderingParams { static constexpr FontQuality invalidFontQuality = FontQuality::QualityMask; FontQuality fontQuality = invalidFontQuality; int logPixelsY = USER_DEFAULT_SCREEN_DPI; + int deviceScaleFactor = 1; std::shared_ptr renderingParams; void Clear() noexcept; void SetFontQuality(FontQuality extraFontFlag); HRESULT GetBitmap(ID2D1Bitmap **ppBitmap); + void SetDeviceScaleFactor(const ID2D1RenderTarget *const pRenderTarget) noexcept; public: SurfaceD2D() noexcept; @@ -1381,6 +1432,7 @@ SurfaceD2D::SurfaceD2D(ID2D1RenderTarget *pRenderTargetCompatible, int width, in &desiredSize, nullptr, &desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &pBitmapRenderTarget); if (SUCCEEDED(hr)) { pRenderTarget = pBitmapRenderTarget; + SetDeviceScaleFactor(pRenderTarget); pRenderTarget->BeginDraw(); ownRenderTarget = true; } @@ -1439,6 +1491,7 @@ void SurfaceD2D::Init(SurfaceID sid, WindowID wid) { Release(); SetScale(wid); pRenderTarget = static_cast(sid); + SetDeviceScaleFactor(pRenderTarget); } std::unique_ptr SurfaceD2D::AllocatePixMap(int width, int height) { @@ -1487,9 +1540,15 @@ int SurfaceD2D::LogPixelsY() { return logPixelsY; } +void SurfaceD2D::SetDeviceScaleFactor(const ID2D1RenderTarget *const pD2D1RenderTarget) noexcept { + FLOAT dpiX = 0.f; + FLOAT dpiY = 0.f; + pD2D1RenderTarget->GetDpi(&dpiX, &dpiY); + deviceScaleFactor = static_cast(dpiX / 96.f); +} + int SurfaceD2D::PixelDivisions() { - // Win32 uses device pixels. - return 1; + return deviceScaleFactor; } int SurfaceD2D::DeviceHeightFont(int points) { @@ -1621,7 +1680,7 @@ void SurfaceD2D::FillRectangle(PRectangle rc, Fill fill) { } void SurfaceD2D::FillRectangleAligned(PRectangle rc, Fill fill) { - FillRectangle(PixelAlign(rc, 1), fill); + FillRectangle(PixelAlign(rc, PixelDivisions()), fill); } void SurfaceD2D::FillRectangle(PRectangle rc, Surface &surfacePattern) { @@ -2895,7 +2954,7 @@ class ListBoxX : public ListBox { PRectangle rcPreSize; Point dragOffset; Point location; // Caret location at which the list is opened - int wheelDelta; // mouse wheel residue + MouseWheelDelta wheelDelta; ListOptions options; DWORD frameStyle = WS_THICKFRAME; @@ -2927,7 +2986,7 @@ public: desiredVisibleRows(9), maxItemCharacters(0), aveCharWidth(8), parent(nullptr), ctrlID(0), dpi(USER_DEFAULT_SCREEN_DPI), delegate(nullptr), - widestItem(nullptr), maxCharWidth(1), resizeHit(0), wheelDelta(0) { + widestItem(nullptr), maxCharWidth(1), resizeHit(0) { } ListBoxX(const ListBoxX &) = delete; ListBoxX(ListBoxX &&) = delete; @@ -3689,21 +3748,15 @@ LRESULT ListBoxX::WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam } return ::DefWindowProc(hWnd, iMessage, wParam, lParam); case WM_MOUSEWHEEL: - wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); - if (std::abs(wheelDelta) >= WHEEL_DELTA) { + if (wheelDelta.Accumulate(wParam)) { const int nRows = GetVisibleRows(); int linesToScroll = std::clamp(nRows - 1, 1, 3); - linesToScroll *= (wheelDelta / WHEEL_DELTA); + linesToScroll *= wheelDelta.Actions(); int top = ListBox_GetTopIndex(lb) + linesToScroll; if (top < 0) { top = 0; } ListBox_SetTopIndex(lb, top); - // update wheel delta residue - if (wheelDelta >= 0) - wheelDelta = wheelDelta % WHEEL_DELTA; - else - wheelDelta = - (-wheelDelta % WHEEL_DELTA); } break; diff --git a/ext/scintilla/win32/PlatWin.h b/ext/scintilla/win32/PlatWin.h index eacc43196..54cd687e9 100644 --- a/ext/scintilla/win32/PlatWin.h +++ b/ext/scintilla/win32/PlatWin.h @@ -43,12 +43,29 @@ inline HWND HwndFromWindow(const Window &w) noexcept { void *PointerFromWindow(HWND hWnd) noexcept; void SetWindowPointer(HWND hWnd, void *ptr) noexcept; +HMONITOR MonitorFromWindowHandleScaling(HWND hWnd) noexcept; + UINT DpiForWindow(WindowID wid) noexcept; +int GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept; int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept; HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept; +class MouseWheelDelta { + int wheelDelta = 0; +public: + bool Accumulate(WPARAM wParam) noexcept { + wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); + return std::abs(wheelDelta) >= WHEEL_DELTA; + } + int Actions() noexcept { + const int actions = wheelDelta / WHEEL_DELTA; + wheelDelta = wheelDelta % WHEEL_DELTA; + return actions; + } +}; + #if defined(USE_D2D) extern bool LoadD2D(); extern ID2D1Factory *pD2DFactory; diff --git a/ext/scintilla/win32/ScintRes.rc b/ext/scintilla/win32/ScintRes.rc index 41931832e..f1221ecfa 100644 --- a/ext/scintilla/win32/ScintRes.rc +++ b/ext/scintilla/win32/ScintRes.rc @@ -4,8 +4,8 @@ #include -#define VERSION_SCINTILLA "5.3.1" -#define VERSION_WORDS 5, 3, 1, 0 +#define VERSION_SCINTILLA "5.3.2" +#define VERSION_WORDS 5, 3, 2, 0 VS_VERSION_INFO VERSIONINFO FILEVERSION VERSION_WORDS diff --git a/ext/scintilla/win32/ScintillaWin.cxx b/ext/scintilla/win32/ScintillaWin.cxx index 8b5f8ffae..b460d1fe2 100644 --- a/ext/scintilla/win32/ScintillaWin.cxx +++ b/ext/scintilla/win32/ScintillaWin.cxx @@ -276,20 +276,6 @@ public: } }; -class MouseWheelDelta { - int wheelDelta = 0; -public: - bool Accumulate(WPARAM wParam) noexcept { - wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); - return std::abs(wheelDelta) >= WHEEL_DELTA; - } - int Actions() noexcept { - const int actions = wheelDelta / WHEEL_DELTA; - wheelDelta = wheelDelta % WHEEL_DELTA; - return actions; - } -}; - struct HorizontalScrollRange { int pageWidth; int documentWidth; @@ -338,6 +324,8 @@ class ScintillaWin : static ATOM scintillaClassAtom; static ATOM callClassAtom; + int deviceScaleFactor = 1; + #if defined(USE_D2D) ID2D1RenderTarget *pRenderTarget; bool renderTargetValid; @@ -433,7 +421,6 @@ class ScintillaWin : void SetCtrlID(int identifier) override; int GetCtrlID() override; void NotifyParent(NotificationData scn) override; - virtual void NotifyParent(SCNotification *scn); void NotifyDoubleClick(Point pt, KeyMod modifiers) override; std::unique_ptr CaseFolderForEncoding() override; std::string CaseMapString(const std::string &s, CaseMapping caseMapping) override; @@ -618,7 +605,8 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { return false; } } - HMONITOR monitor = ::MonitorFromWindow(MainHWND(), MONITOR_DEFAULTTONEAREST); + const HWND hRootWnd = ::GetAncestor(MainHWND(), GA_ROOT); + const HMONITOR monitor = Internal::MonitorFromWindowHandleScaling(hRootWnd); if (!force && monitor == hCurrentMonitor && renderingParams->defaultRenderingParams) { return false; } @@ -640,11 +628,23 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { } hCurrentMonitor = monitor; + deviceScaleFactor = Internal::GetDeviceScaleFactorWhenGdiScalingActive(hRootWnd); renderingParams->defaultRenderingParams.reset(monitorRenderingParams); renderingParams->customRenderingParams.reset(customClearTypeRenderingParams); return true; } +namespace { + +D2D1_SIZE_U GetSizeUFromRect(const RECT &rc, const int scaleFactor) noexcept { + const long width = rc.right - rc.left; + const long height = rc.bottom - rc.top; + const UINT32 scaledWidth = width * scaleFactor; + const UINT32 scaledHeight = height * scaleFactor; + return D2D1::SizeU(scaledWidth, scaledHeight); +} + +} void ScintillaWin::EnsureRenderTarget(HDC hdc) { if (!renderTargetValid) { @@ -656,19 +656,15 @@ void ScintillaWin::EnsureRenderTarget(HDC hdc) { RECT rc; ::GetClientRect(hw, &rc); - const D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); - // Create a Direct2D render target. D2D1_RENDER_TARGET_PROPERTIES drtp {}; drtp.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; - drtp.pixelFormat.format = DXGI_FORMAT_UNKNOWN; - drtp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; - drtp.dpiX = 96.0; - drtp.dpiY = 96.0; drtp.usage = D2D1_RENDER_TARGET_USAGE_NONE; drtp.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; if (technology == Technology::DirectWriteDC) { + drtp.dpiX = 96.f; + drtp.dpiY = 96.f; // Explicit pixel format needed. drtp.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE); @@ -683,9 +679,14 @@ void ScintillaWin::EnsureRenderTarget(HDC hdc) { } } else { + drtp.dpiX = 96.f * deviceScaleFactor; + drtp.dpiY = 96.f * deviceScaleFactor; + drtp.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, + D2D1_ALPHA_MODE_UNKNOWN); + D2D1_HWND_RENDER_TARGET_PROPERTIES dhrtp {}; dhrtp.hwnd = hw; - dhrtp.pixelSize = size; + dhrtp.pixelSize = ::GetSizeUFromRect(rc, deviceScaleFactor); dhrtp.presentOptions = (technology == Technology::DirectWriteRetain) ? D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS : D2D1_PRESENT_OPTIONS_NONE; @@ -2455,13 +2456,6 @@ void ScintillaWin::NotifyParent(NotificationData scn) { GetCtrlID(), reinterpret_cast(&scn)); } -void ScintillaWin::NotifyParent(SCNotification *scn) { - scn->nmhdr.hwndFrom = MainHWND(); - scn->nmhdr.idFrom = GetCtrlID(); - ::SendMessage(::GetParent(MainHWND()), WM_NOTIFY, - GetCtrlID(), reinterpret_cast(scn)); -} - void ScintillaWin::NotifyDoubleClick(Point pt, KeyMod modifiers) { //Platform::DebugPrintf("ScintillaWin Double click 0\n"); ScintillaBase::NotifyDoubleClick(pt, modifiers); @@ -3615,10 +3609,12 @@ LRESULT PASCAL ScintillaWin::CTWndProc( surfaceWindow->Init(ps.hdc, hWnd); } else { #if defined(USE_D2D) + const int scaleFactor = sciThis->deviceScaleFactor; + // Create a Direct2D render target. D2D1_HWND_RENDER_TARGET_PROPERTIES dhrtp {}; dhrtp.hwnd = hWnd; - dhrtp.pixelSize = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); + dhrtp.pixelSize = ::GetSizeUFromRect(rc, scaleFactor); dhrtp.presentOptions = (sciThis->technology == Technology::DirectWriteRetain) ? D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS : D2D1_PRESENT_OPTIONS_NONE; @@ -3626,8 +3622,8 @@ LRESULT PASCAL ScintillaWin::CTWndProc( drtp.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; drtp.pixelFormat.format = DXGI_FORMAT_UNKNOWN; drtp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; - drtp.dpiX = 96.0; - drtp.dpiY = 96.0; + drtp.dpiX = 96.f * scaleFactor; + drtp.dpiY = 96.f * scaleFactor; drtp.usage = D2D1_RENDER_TARGET_USAGE_NONE; drtp.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; diff --git a/ext/scintilla/win32/makefile b/ext/scintilla/win32/makefile index 39aac8bcb..207bc9d0f 100644 --- a/ext/scintilla/win32/makefile +++ b/ext/scintilla/win32/makefile @@ -57,7 +57,7 @@ DEFINES += -DNO_CXX11_REGEX endif DEFINES += -D$(if $(DEBUG),DEBUG,NDEBUG) -BASE_FLAGS += $(if $(DEBUG),-g,-Os) +BASE_FLAGS += $(if $(DEBUG),-g,-O3) ifndef DEBUG STRIPFLAG=$(STRIPOPTION) diff --git a/ext/scintilla/win32/scintilla.mak b/ext/scintilla/win32/scintilla.mak index e5f1a1ad3..bf21cc88d 100644 --- a/ext/scintilla/win32/scintilla.mak +++ b/ext/scintilla/win32/scintilla.mak @@ -38,7 +38,7 @@ SUBSYSTEM=-SUBSYSTEM:WINDOWS,10.00 CRTFLAGS=-D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 -D_CRT_SECURE_NO_DEPRECATE=1 -D_SCL_SECURE_NO_WARNINGS=1 $(ADD_DEFINE) CXXFLAGS=-Zi -TP -MP -W4 -EHsc -std:c++17 $(CRTFLAGS) CXXDEBUG=-Od -MTd -DDEBUG -CXXNDEBUG=-O1 -MT -DNDEBUG -GL +CXXNDEBUG=-O2 -MT -DNDEBUG -GL NAME=-Fo LDFLAGS=-OPT:REF -LTCG -IGNORE:4197 -DEBUG $(SUBSYSTEM) $(CETCOMPAT) LDDEBUG= -- 2.11.4.GIT