From 83581f8d8c9f9d1e67116e889f6a591a118cbd54 Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Fri, 20 Feb 2026 13:40:34 +0100 Subject: [PATCH 1/3] fix: if flag 'strip trailing blanks on save' is active, check if there are trailing blanks in document for "saving needed". - minor fixes in some editing functions --- src/Edit.c | 175 +++++++++++++++++++++++++++++-------------------- src/Edit.h | 1 + src/Notepad3.c | 2 +- 3 files changed, 105 insertions(+), 73 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index 7268373be..dec1faeba 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -1552,7 +1552,7 @@ bool EditSaveFile( } // strip trailing blanks - if (Settings.FixTrailingBlanks) { + if (Settings.FixTrailingBlanks && EditHasTrailingBlanks()) { EditStripLastCharacter(hwnd, true, true); } } @@ -2694,6 +2694,7 @@ void EditTabsToSpaces(int nTabWidth,bool bOnlyIndentingWS) if (bModified) { char * const pszText2 = AllocMem((size_t)cchConvW * 3, HEAP_ZERO_MEMORY); + if (pszText2) { ptrdiff_t cchConvM = WideCharToMultiByteEx(Encoding_SciCP,0,pszConvW,cchConvW, pszText2,SizeOfMem(pszText2),NULL,NULL); @@ -2711,6 +2712,8 @@ void EditTabsToSpaces(int nTabWidth,bool bOnlyIndentingWS) Sci_ReplaceTargetTestChgHist(cchConvM, pszText2); EditSetSelectionEx(iAnchorPos, iCurPos, -1, -1); EndUndoTransAction(); + + } // if pszText2 FreeMem(pszText2); } FreeMem(pszConvW); @@ -2806,6 +2809,7 @@ void EditSpacesToTabs(int nTabWidth,bool bOnlyIndentingWS) if (bModified || cchConvW != cchTextW) { char *pszText2 = AllocMem((size_t)cchConvW * 3, HEAP_ZERO_MEMORY); + if (pszText2) { ptrdiff_t cchConvM = WideCharToMultiByteEx(Encoding_SciCP,0,pszConvW,cchConvW, pszText2,SizeOfMem(pszText2),NULL,NULL); @@ -2823,6 +2827,8 @@ void EditSpacesToTabs(int nTabWidth,bool bOnlyIndentingWS) Sci_ReplaceTargetTestChgHist(cchConvM, pszText2); EditSetSelectionEx(iAnchorPos, iCurPos, -1, -1); EndUndoTransAction(); + + } // if pszText2 FreeMem(pszText2); } @@ -3202,7 +3208,7 @@ void EditModifyLines(const PENCLOSESELDATA pEnclData) { *q = '\0'; // terminate tinyexpr StringCchCopyA(mszTinyExprPost, COUNTOF(mszTinyExprPost), t); StringCchCopyA(mszAppend2, COUNTOF(mszAppend2), q + CONSTSTRGLEN(EXPR_END)); - *p = '\0'; // mszPrefix1 terminate + *p = '\0'; // mszAppend1 terminate p = StrStrA(q, EXPR_BEG); // next } else { @@ -3230,7 +3236,7 @@ void EditModifyLines(const PENCLOSESELDATA pEnclData) { N = I + 1.0; DocLn vmin = d2ln(te_eval(pTinyExprPre)); DocLn vmax = vmin; - for (DocLn ln = iStartLine + 2; ln <= iEndLine; ++ln) { + for (DocLn ln = iStartLine + 2; ln <= iEndLine + 1; ++ln) { L = (double)ln; I += 1.0; N += 1.0; @@ -3271,7 +3277,7 @@ void EditModifyLines(const PENCLOSESELDATA pEnclData) { N = I + 1.0; DocLn vmin = d2ln(te_eval(pTinyExprPost)); DocLn vmax = vmin; - for (DocLn ln = iStartLine + 2; ln <= iEndLine; ++ln) { + for (DocLn ln = iStartLine + 2; ln <= iEndLine + 1; ++ln) { L = (double)ln; I += 1.0; N += 1.0; @@ -3379,7 +3385,7 @@ void EditModifyLines(const PENCLOSESELDATA pEnclData) { DocPos const newPos = SciCall_PositionFromLine(iResetLine) + iResetOffset + prefixInsertLen; EditSetSelectionEx(newPos, newPos, -1, -1); } - else if (iSelStart != iSelEnd) { + else { if (iResetPos < iAnchorPos) { EditSetSelectionEx(SciCall_PositionFromLine(iEndLine + 1), SciCall_PositionFromLine(iStartLine), -1, -1); } else { @@ -3482,9 +3488,9 @@ void EditIndentBlock(HWND hwnd, int cmd, bool bFormatIndentation, bool bForceAll } else { // on multiline indentation, anchor and current positions are moved to line begin resp. end if (bFixStart) { if (iCurPos < iAnchorPos) { - iDiffCurrent = SciCall_LineLength(iCurLine) - Sci_GetEOLLen(); + iDiffCurrent = SciCall_GetLineEndPosition(iCurLine) - SciCall_PositionFromLine(iCurLine); } else { - iDiffAnchor = SciCall_LineLength(iAnchorLine) - Sci_GetEOLLen(); + iDiffAnchor = SciCall_GetLineEndPosition(iAnchorLine) - SciCall_PositionFromLine(iAnchorLine); } } EditSetSelectionEx(SciCall_GetLineEndPosition(iAnchorLine) - iDiffAnchor, SciCall_GetLineEndPosition(iCurLine) - iDiffCurrent, -1, -1); @@ -3535,9 +3541,10 @@ void EditAlignText(int nMode) if (iLineIndentPos != iLineEndPos) { int const iIndentCol = SciCall_GetLineIndentation(iLine); + DocPos const iLineStartPos = SciCall_PositionFromLine(iLine); DocPos iTail = iLineEndPos - 1; char ch = SciCall_GetCharAt(iTail); - while (iTail >= iLineStart && (ch == ' ' || ch == '\t')) { + while (iTail >= iLineStartPos && (ch == ' ' || ch == '\t')) { --iTail; ch = SciCall_GetCharAt(iTail); --iLineEndPos; @@ -3557,7 +3564,7 @@ void EditAlignText(int nMode) UndoTransActionBegin(); - if (chNewLineBuf && wchLineBuf && wchNewLineBuf) { + if (chNewLineBuf && wchLineBuf && wchNewLineBuf && pWords) { for (DocLn iLine = iLineStart; iLine <= iLineEnd; iLine++) { DocPos const iStartPos = SciCall_PositionFromLine(iLine); @@ -3608,8 +3615,7 @@ void EditAlignText(int nMode) } } - if ((nMode == ALIGN_JUSTIFY || nMode == ALIGN_JUSTIFY_EX) && - iWords > 1 && iWordsLength >= 2 && + if (iWords > 1 && iWordsLength >= 2 && ((nMode != ALIGN_JUSTIFY_EX || !bNextLineIsBlank || iLineStart == iLineEnd) || (bNextLineIsBlank && iWordsLength > (iMaxLength - iMinIndent) * 0.75))) { int iGaps = iWords - 1; @@ -3704,15 +3710,15 @@ void EditAlignText(int nMode) } } - FreeMem(pWords); - FreeMem(wchNewLineBuf); - FreeMem(wchLineBuf); - FreeMem(chNewLineBuf); - } else { InfoBoxLng(MB_ICONERROR, NULL, IDS_MUI_BUFFERTOOSMALL); } + FreeMem(pWords); + FreeMem(wchNewLineBuf); + FreeMem(wchLineBuf); + FreeMem(chNewLineBuf); + if (iAnchorPos > iCurPos) { iCurPos = SciCall_FindColumn(iLineStart, iCurCol); iAnchorPos = SciCall_FindColumn(_lnend, iAnchorCol); @@ -3977,6 +3983,7 @@ void EditToggleLineCommentsExtended(LPCWSTR pwszComment, bool bInsertAtStart) switch (iAction) { case 0: iAction = 2; + // fall through case 2: SciCall_SetTargetRange(iIndentPos, iSelPos); Sci_ReplaceTargetTestChgHist(0, ""); @@ -3991,6 +3998,7 @@ void EditToggleLineCommentsExtended(LPCWSTR pwszComment, bool bInsertAtStart) switch (iAction) { case 0: iAction = 1; + // fall through case 1: { DocPos const iPos = SciCall_FindColumn(iLine, iCommentCol); SciCall_InsertText(iPos, mszComment); @@ -4026,7 +4034,7 @@ void EditToggleLineCommentsExtended(LPCWSTR pwszComment, bool bInsertAtStart) // // _AppendSpaces() // -static DocPos _AppendSpaces(HWND hwnd, DocLn iLineStart, DocLn iLineEnd, DocPos iMaxColumn, bool bSkipEmpty) +static DocPos _AppendSpaces(HWND hwnd, DocLn iLineStart, DocLn iLineEnd, DocPos iMaxColumn, bool bSkipEmpty) { UNREFERENCED_PARAMETER(hwnd); @@ -4080,7 +4088,7 @@ void EditPadWithSpaces(HWND hwnd, bool bSkipEmpty) { //~UndoTransActionBegin(); // outside defined - if (Sci_IsMultiOrRectangleSelection() && !SciCall_IsSelectionEmpty()) { + if (Sci_IsMultiOrRectangleSelection()) { DocPos const selAnchorMainPos = SciCall_GetRectangularSelectionAnchor(); DocPos const selCaretMainPos = SciCall_GetRectangularSelectionCaret(); @@ -4094,52 +4102,55 @@ void EditPadWithSpaces(HWND hwnd, bool bSkipEmpty) { DocLn const iLineCount = abs_p(iRcCaretLine - iRcAnchorLine) + 1; // lots of spaces - DocPos const spBufSize = max_p(iAnchorColumn, selCaretMainPos); + DocPos const spBufSize = max_p(iAnchorColumn, iCaretColumn); char * const pSpaceBuffer = (char *)AllocMem((spBufSize + 1) * sizeof(char), HEAP_ZERO_MEMORY); - FillMemory(pSpaceBuffer, spBufSize * sizeof(char), ' '); DocPos * const pVspAVec = (DocPos *)AllocMem(iLineCount * sizeof(DocPos), HEAP_ZERO_MEMORY); DocPos * const pVspCVec = (DocPos *)AllocMem(iLineCount * sizeof(DocPos), HEAP_ZERO_MEMORY); - for (DocLn i = 0; i < iLineCount; ++i) { - pVspAVec[i] = SciCall_GetSelectionNAnchorVirtualSpace(i); - pVspCVec[i] = SciCall_GetSelectionNCaretVirtualSpace(i); - } + if (pSpaceBuffer && pVspAVec && pVspCVec) { - DocPos i = 0; - DocPos iSpcCount = 0; - DocLn const iLnIncr = (iRcAnchorLine <= iRcCaretLine) ? ((DocLn)+1) : ((DocLn)-1); - DocLn iLine = iRcAnchorLine - iLnIncr; - do { - iLine += iLnIncr; - DocPos const iInsPos = SciCall_GetLineEndPosition(iLine); - DocPos const cntVSp = bSelLeft2Right ? pVspCVec[i++] : pVspAVec[i++]; - bool const bSkip = (bSkipEmpty && (iInsPos <= SciCall_PositionFromLine(iLine))); + FillMemory(pSpaceBuffer, spBufSize * sizeof(char), ' '); - if ((cntVSp > 0) && !bSkip) { - pSpaceBuffer[cntVSp] = '\0'; - SciCall_InsertText(iInsPos, pSpaceBuffer); - pSpaceBuffer[cntVSp] = ' '; - iSpcCount += cntVSp; + for (DocLn i = 0; i < iLineCount; ++i) { + pVspAVec[i] = SciCall_GetSelectionNAnchorVirtualSpace(i); + pVspCVec[i] = SciCall_GetSelectionNCaretVirtualSpace(i); } - } while ((iLine != iRcCaretLine) && (i < iLineCount)); - FreeMem(pSpaceBuffer); + DocPos i = 0; + DocPos iSpcCount = 0; + DocLn const iLnIncr = (iRcAnchorLine <= iRcCaretLine) ? ((DocLn)+1) : ((DocLn)-1); + DocLn iLine = iRcAnchorLine - iLnIncr; + do { + iLine += iLnIncr; + DocPos const iInsPos = SciCall_GetLineEndPosition(iLine); + DocPos const cntVSp = bSelLeft2Right ? pVspCVec[i++] : pVspAVec[i++]; + bool const bSkip = (bSkipEmpty && (iInsPos <= SciCall_PositionFromLine(iLine))); + + if ((cntVSp > 0) && !bSkip) { + pSpaceBuffer[cntVSp] = '\0'; + SciCall_InsertText(iInsPos, pSpaceBuffer); + pSpaceBuffer[cntVSp] = ' '; + iSpcCount += cntVSp; + } + } while ((iLine != iRcCaretLine) && (i < iLineCount)); - if (iRcAnchorLine <= iRcCaretLine) { - if (bSelLeft2Right) { - EditSetSelectionEx(selAnchorMainPos + pVspAVec[0], selCaretMainPos + iSpcCount, 0, 0); - } else { - EditSetSelectionEx(selAnchorMainPos + pVspAVec[0], selCaretMainPos + pVspCVec[iLineCount - 1] + iSpcCount - pVspAVec[iLineCount - 1], 0, 0); - } - } else { - if (bSelLeft2Right) { - EditSetSelectionEx(selAnchorMainPos + pVspAVec[0] + iSpcCount - pVspCVec[0], selCaretMainPos + pVspCVec[iLineCount - 1], 0, 0); + if (iRcAnchorLine <= iRcCaretLine) { + if (bSelLeft2Right) { + EditSetSelectionEx(selAnchorMainPos + pVspAVec[0], selCaretMainPos + iSpcCount, 0, 0); + } else { + EditSetSelectionEx(selAnchorMainPos + pVspAVec[0], selCaretMainPos + pVspCVec[iLineCount - 1] + iSpcCount - pVspAVec[iLineCount - 1], 0, 0); + } } else { - EditSetSelectionEx(selAnchorMainPos + iSpcCount, selCaretMainPos + pVspCVec[iLineCount - 1], 0, 0); + if (bSelLeft2Right) { + EditSetSelectionEx(selAnchorMainPos + pVspAVec[0] + iSpcCount - pVspCVec[0], selCaretMainPos + pVspCVec[iLineCount - 1], 0, 0); + } else { + EditSetSelectionEx(selAnchorMainPos + iSpcCount, selCaretMainPos + pVspCVec[iLineCount - 1], 0, 0); + } } } + FreeMem(pSpaceBuffer); FreeMem(pVspCVec); FreeMem(pVspAVec); @@ -4151,15 +4162,10 @@ void EditPadWithSpaces(HWND hwnd, bool bSkipEmpty) { const DocPos iSelStart = SciCall_GetSelectionStart(); const DocPos iSelEnd = SciCall_GetSelectionEnd(); - DocLn iStartLine = 0; - DocLn iEndLine = Sci_GetLastDocLineNumber(); - - if (iSelStart != iSelEnd) { - iStartLine = SciCall_LineFromPosition(iSelStart); - iEndLine = SciCall_LineFromPosition(iSelEnd); - if (iSelEnd < SciCall_GetLineEndPosition(iEndLine)) { - --iEndLine; - } + DocLn iStartLine = SciCall_LineFromPosition(iSelStart); + DocLn iEndLine = SciCall_LineFromPosition(iSelEnd); + if (iSelEnd < SciCall_GetLineEndPosition(iEndLine)) { + --iEndLine; } if (iStartLine < iEndLine) { DocPos iMaxColumn = 0; @@ -4193,8 +4199,8 @@ void EditStripFirstCharacter(HWND hwnd) return; } - DocPos const iSelStart = SciCall_IsSelectionEmpty() ? 0 : SciCall_GetSelectionStart(); - DocPos const iSelEnd = SciCall_IsSelectionEmpty() ? Sci_GetDocEndPosition() : SciCall_GetSelectionEnd(); + DocPos const iSelStart = SciCall_GetSelectionStart(); + DocPos const iSelEnd = SciCall_GetSelectionEnd(); DocLn const iLineStart = SciCall_LineFromPosition(iSelStart); DocLn const iLineEnd = SciCall_LineFromPosition(iSelEnd); @@ -4220,8 +4226,8 @@ void EditStripFirstCharacter(HWND hwnd) StringCchCopyNA(lineBuffer, SizeOfMem(lineBuffer), SciCall_GetRangePointer(nextPos, len + 1), len); SciCall_SetTargetRange(selTargetStart, selTargetEnd); Sci_ReplaceTargetTestChgHist(len, lineBuffer); + remCount += (nextPos - selTargetStart); } - remCount += (nextPos - selTargetStart); } // for() FreeMem(lineBuffer); } @@ -4313,8 +4319,10 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan lineBuffer[++i] = lineBuffer[end++]; // add "\r\n" if any } diff = len - (++i); - SciCall_SetTargetRange(selTargetStart, selTargetEnd); - Sci_ReplaceTargetTestChgHist(-1, lineBuffer); + if (diff > 0) { + SciCall_SetTargetRange(selTargetStart, selTargetEnd); + Sci_ReplaceTargetTestChgHist(-1, lineBuffer); + } } } else { DocPos const prevPos = SciCall_PositionBefore(selTargetEnd); @@ -4347,14 +4355,16 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan DocPos const iEndPos = SciCall_GetLineEndPosition(iLine); if (bTrailingBlanksOnly) { - DocPos i = iEndPos; - char ch = '\0'; - do { - ch = SciCall_GetCharAt(--i); - } while ((i >= iStartPos) && IsBlankCharA(ch)); - if ((++i) < iEndPos) { - SciCall_SetTargetRange(i, iEndPos); - Sci_ReplaceTargetTestChgHist(0, ""); + if (iStartPos < iEndPos) { + DocPos i = iEndPos; + char ch = '\0'; + do { + ch = SciCall_GetCharAt(--i); + } while ((i >= iStartPos) && IsBlankCharA(ch)); + if ((++i) < iEndPos) { + SciCall_SetTargetRange(i, iEndPos); + Sci_ReplaceTargetTestChgHist(0, ""); + } } } else { // any char at line end if (iStartPos < iEndPos) { @@ -4371,6 +4381,27 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan } +//============================================================================= +// +// EditHasTrailingBlanks() +// +bool EditHasTrailingBlanks() +{ + DocLn const iLineCount = SciCall_GetLineCount(); + for (DocLn iLine = 0; iLine < iLineCount; ++iLine) { + DocPos const iStartPos = SciCall_PositionFromLine(iLine); + DocPos const iEndPos = SciCall_GetLineEndPosition(iLine); + if (iEndPos > iStartPos) { + char const ch = SciCall_GetCharAt(iEndPos - 1); + if (IsBlankCharA(ch)) { + return true; + } + } + } + return false; +} + + //============================================================================= // // EditCompressBlanks() diff --git a/src/Edit.h b/src/Edit.h index 235902f97..0f040b37e 100644 --- a/src/Edit.h +++ b/src/Edit.h @@ -80,6 +80,7 @@ void EditToggleLineCommentsExtended(LPCWSTR pwszComment, bool bInsertAtStart); void EditPadWithSpaces(HWND hwnd, bool bSkipEmpty); void EditStripFirstCharacter(HWND hwnd); void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlanksOnly); +bool EditHasTrailingBlanks(); void EditCompressBlanks(); void EditRemoveBlankLines(HWND hwnd, bool bMerge, bool bRemoveWhiteSpace); void EditUniteDuplicateLines(HWND hwnd, bool bRemoveEmptyLines, bool bRemoveLastDup); diff --git a/src/Notepad3.c b/src/Notepad3.c index 91fea3377..5d9bffbb2 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -11390,7 +11390,7 @@ bool FileSave(FileSaveFlags fSaveFlags) } } - bool const bSaveNeeded = (IsSaveNeeded() || IsFileChangedFlagSet() || Settings.FixTrailingBlanks) && !bIsEmptyNewFile; + bool const bSaveNeeded = (IsSaveNeeded() || IsFileChangedFlagSet() || (Settings.FixTrailingBlanks && EditHasTrailingBlanks())) && !bIsEmptyNewFile; if (!(fSaveFlags & FSF_SaveAs) && !(fSaveFlags & FSF_SaveAlways) && !bSaveNeeded) { _MRU_UpdateSession(); From 399b95a5b1d02fe047632f847fc6b54ef59990bd Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Fri, 20 Feb 2026 16:58:02 +0100 Subject: [PATCH 2/3] fix: Zooming --- scintilla/include/Scintilla.h | 2 - scintilla/include/Scintilla.iface | 6 -- scintilla/src/EditView.cxx | 4 +- scintilla/src/ViewStyle.cxx | 50 +--------------- scintilla/src/ViewStyle.h | 16 +---- scintilla/win32/ScintillaWin.cxx | 19 ++---- src/Config/Config.cpp | 6 +- src/Dialogs.c | 4 +- src/Notepad3.c | 97 ++++++++++++++++++++++++++----- src/Notepad3.h | 5 ++ src/Print.cpp | 7 ++- src/Styles.c | 4 +- src/TypeDefs.h | 8 +++ 13 files changed, 117 insertions(+), 111 deletions(-) diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index c29cf44da..066289357 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -863,8 +863,6 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_POPUP_TEXT 2 #define SCI_USEPOPUP 2371 #define SCI_SELECTIONISRECTANGLE 2372 -#define SC_MIN_ZOOM_LEVEL 10 -#define SC_MAX_ZOOM_LEVEL 1000 #define SCI_SETZOOM 2373 #define SCI_GETZOOM 2374 #define SC_DOCUMENTOPTION_DEFAULT 0 diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface index 3f9e5988d..a44073192 100644 --- a/scintilla/include/Scintilla.iface +++ b/scintilla/include/Scintilla.iface @@ -2265,12 +2265,6 @@ fun void UsePopUp=2371(PopUp popUpMode,) # Is the selection rectangular? The alternative is the more common stream selection. get bool SelectionIsRectangle=2372(,) -# >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> -# 2018-09-06 change zoom level and print magnification to percent value -val SC_MIN_ZOOM_LEVEL=10 -val SC_MAX_ZOOM_LEVEL=1000 -# <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< - # Set the zoom level. This number of points is added to the size of all fonts. # It may be positive to magnify or negative to reduce. set void SetZoom=2373(int zoomInPoints,) diff --git a/scintilla/src/EditView.cxx b/scintilla/src/EditView.cxx index 749af561a..7215307fa 100644 --- a/scintilla/src/EditView.cxx +++ b/scintilla/src/EditView.cxx @@ -71,9 +71,7 @@ using namespace Scintilla; using namespace Scintilla::Internal; PrintParameters::PrintParameters() noexcept { - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - magnification = 100; - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< + magnification = 0; colourMode = PrintOption::Normal; wrapState = Wrap::Word; } diff --git a/scintilla/src/ViewStyle.cxx b/scintilla/src/ViewStyle.cxx index da7d7fd06..75370f04b 100644 --- a/scintilla/src/ViewStyle.cxx +++ b/scintilla/src/ViewStyle.cxx @@ -63,12 +63,8 @@ bool MarginStyle::ShowsFolding() const noexcept { void FontRealised::Realise(Surface &surface, int zoomLevel, Technology technology, const FontSpecification &fs, const char *localeName) { PLATFORM_ASSERT(fs.fontName); - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - //~measurements.sizeZoomed = fs.size + zoomLevel * FontSizeMultiplier; - //~if (measurements.sizeZoomed <= FontSizeMultiplier) // May fail if sizeZoomed < 1 - //~ measurements.sizeZoomed = FontSizeMultiplier; - measurements.sizeZoomed = GetFontSizeZoomed(fs.size, zoomLevel); - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< + // If negative zoomLevel, ensure sizeZoomed at least minimum positive size + measurements.sizeZoomed = std::max(fs.size + (zoomLevel * FontSizeMultiplier), FontSizeMultiplier); const float deviceHeight = static_cast(surface.DeviceHeightFont(measurements.sizeZoomed)); const FontParameters fp(fs.fontName, deviceHeight / FontSizeMultiplier, fs.weight, @@ -234,9 +230,7 @@ ViewStyle::ViewStyle(size_t stylesSize_) : marginInside = true; CalculateMarginWidthAndMask(); textStart = marginInside ? fixedColumnWidth : leftMarginWidth; - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - zoomLevel = 100; /// @ 20018-09-06 Changed to percent - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< + zoomLevel = 0; viewWhitespace = WhiteSpace::Invisible; tabDrawMode = TabDrawMode::LongArrow; whitespaceSize = 1; @@ -771,44 +765,6 @@ ViewStyle::CaretShape ViewStyle::CaretShapeForMode(bool inOverstrike, bool isMai return (caretStyle <= CaretStyle::Block) ? static_cast(caretStyle) : CaretShape::line; } -// >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> -bool ViewStyle::ZoomIn() noexcept { - if (zoomLevel < SC_MAX_ZOOM_LEVEL) { - int level = zoomLevel; - if (level < 200) { - level += 10; - } else { - level += 25; - } - - level = std::min(level, SC_MAX_ZOOM_LEVEL); - if (level != zoomLevel) { - zoomLevel = level; - return true; - } - } - return false; -} - -bool ViewStyle::ZoomOut() noexcept { - if (zoomLevel > SC_MIN_ZOOM_LEVEL) { - int level = zoomLevel; - if (level <= 200) { - level -= 10; - } else { - level -= 25; - } - - level = std::max(level, SC_MIN_ZOOM_LEVEL); - if (level != zoomLevel) { - zoomLevel = level; - return true; - } - } - return false; -} -// <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< - void ViewStyle::AllocStyles(size_t sizeNew) { size_t i=styles.size(); styles.resize(sizeNew); diff --git a/scintilla/src/ViewStyle.h b/scintilla/src/ViewStyle.h index 28474d536..4e4ea0d73 100644 --- a/scintilla/src/ViewStyle.h +++ b/scintilla/src/ViewStyle.h @@ -71,14 +71,6 @@ struct CaretLineAppearance { int frame = 0; }; -// >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> -constexpr int GetFontSizeZoomed(int size, int zoomLevel) noexcept { - size = (size * zoomLevel + 50) / 100; - // Hangs if sizeZoomed (in point) <= 1 - return std::max(size, 2 * FontSizeMultiplier); -} -// <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< - struct CaretAppearance { // Line, block, over-strike bar ... Scintilla::CaretStyle style = CaretStyle::Line; @@ -160,9 +152,7 @@ class ViewStyle { int fixedColumnWidth = 0; ///< Total width of margins bool marginInside; ///< true: margin included in text view, false: separate views int textStart; ///< Starting x position of text within the view - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - int zoomLevel; /// @ 2018-09-06 Changed to a percent value - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< + int zoomLevel; Scintilla::WhiteSpace viewWhitespace; Scintilla::TabDrawMode tabDrawMode; int whitespaceSize; @@ -259,10 +249,6 @@ class ViewStyle { bool IsCaretVisible(bool isMainSelection) const noexcept; bool DrawCaretInsideSelection(bool inOverstrike, bool imeCaretBlockOverride) const noexcept; CaretShape CaretShapeForMode(bool inOverstrike, bool isMainSelection) const noexcept; - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - bool ZoomIn() noexcept; - bool ZoomOut() noexcept; - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< private: void AllocStyles(size_t sizeNew); diff --git a/scintilla/win32/ScintillaWin.cxx b/scintilla/win32/ScintillaWin.cxx index e39656e88..54f89e0b7 100644 --- a/scintilla/win32/ScintillaWin.cxx +++ b/scintilla/win32/ScintillaWin.cxx @@ -333,12 +333,9 @@ class IMContext { void SetCompositionFont(const ViewStyle &vs, int style, UINT dpi) const { LOGFONTW lf{}; - // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - //int sizeZoomed = vs.styles[style].size + (vs.zoomLevel * FontSizeMultiplier); - //if (sizeZoomed <= 2 * FontSizeMultiplier) // Hangs if sizeZoomed <= 1 - // sizeZoomed = 2 * FontSizeMultiplier; - int const sizeZoomed = GetFontSizeZoomed(vs.styles[style].size, vs.zoomLevel); - // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< + int sizeZoomed = vs.styles[style].size + (vs.zoomLevel * FontSizeMultiplier); + if (sizeZoomed <= 2 * FontSizeMultiplier) // Hangs if sizeZoomed <= 1 + sizeZoomed = 2 * FontSizeMultiplier; // The negative is to allow for leading lf.lfHeight = -::MulDiv(sizeZoomed, dpi, pointsPerInch * FontSizeMultiplier); lf.lfWeight = static_cast(vs.styles[style].weight); @@ -1959,15 +1956,7 @@ sptr_t ScintillaWin::MouseMessage(unsigned int iMessage, uptr_t wParam, sptr_t l // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> if (wParam & (MK_CONTROL | MK_RBUTTON)) { - if (wParam & (MK_CONTROL)) { - // Zoom! We play with the font sizes in the styles. - // Number of steps/line is ignored, we just care if sizing up or down - if (linesToScroll < 0) - KeyCommand(Message::ZoomIn); - else - KeyCommand(Message::ZoomOut); - } - // send to main window (trigger zoom callTip or undo/redo history) ! + // Forward to parent (NP3 handles zoom steps and undo/redo history) ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); } else { // Scroll diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index f99b92ba2..4713c610b 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -1713,11 +1713,11 @@ void LoadSettings() int const prtFontSize = 10; int const zoomScale = MulDiv(baseZoom, prtFontSize, f2int(GLOBAL_INITIAL_FONTSIZE)); Defaults.PrintZoom = (Globals.iCfgVersionRead < CFG_VER_0001) ? (zoomScale / 10) : zoomScale; - int iPrintZoom = clampi(IniSectionGetInt(IniSecSettings, L"PrintZoom", Defaults.PrintZoom), 0, SC_MAX_ZOOM_LEVEL); + int iPrintZoom = clampi(IniSectionGetInt(IniSecSettings, L"PrintZoom", Defaults.PrintZoom), 0, NP3_MAX_ZOOM_PERCENT); if (Globals.iCfgVersionRead < CFG_VER_0001) { iPrintZoom = 100 + (iPrintZoom - 10) * 10; } - Settings.PrintZoom = clampi(iPrintZoom, SC_MIN_ZOOM_LEVEL, SC_MAX_ZOOM_LEVEL); + Settings.PrintZoom = clampi(iPrintZoom, NP3_MIN_ZOOM_PERCENT, NP3_MAX_ZOOM_PERCENT); GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_IMEASURE, tchKeyName, COUNTOF(tchKeyName)); LONG const _margin = (tchKeyName[0] == L'0') ? 2000L : 1000L; // Metric system. L'1' is US System @@ -1886,7 +1886,7 @@ void LoadSettings() if (Globals.iCfgVersionRead < CFG_VER_0001) { winInfo.zoom = (winInfo.zoom + 10) * 10; } - winInfo.zoom = clampi(winInfo.zoom, SC_MIN_ZOOM_LEVEL, SC_MAX_ZOOM_LEVEL); + winInfo.zoom = clampi(winInfo.zoom, NP3_MIN_ZOOM_PERCENT, NP3_MAX_ZOOM_PERCENT); winInfo.dpi = IniSectionGetInt(IniSecWindow, tchDPI, USER_DEFAULT_SCREEN_DPI); int const offset = Settings2.LaunchInstanceWndPosOffset; diff --git a/src/Dialogs.c b/src/Dialogs.c index 7982ef72a..d1826cc73 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -1338,7 +1338,7 @@ INT_PTR CALLBACK AboutDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam StringCchPrintf(wchBuf, COUNTOF(wchBuf), L"\n- Rendering-Technology -> '%s'", Settings.RenderingTechnology ? L"DIRECT-WRITE" : L"GDI"); StringCchCat(wchVerInfo, COUNTOF(wchVerInfo), wchBuf); - StringCchPrintf(wchBuf, COUNTOF(wchBuf), L"\n- Zoom -> %i%%.", SciCall_GetZoom()); + StringCchPrintf(wchBuf, COUNTOF(wchBuf), L"\n- Zoom -> %i%%.", NP3_GetZoomPercent()); StringCchCat(wchVerInfo, COUNTOF(wchVerInfo), wchBuf); Style_GetLexerDisplayName(Style_GetCurrentLexerPtr(), wchBuf, COUNTOF(wchBuf)); @@ -4698,7 +4698,7 @@ WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO *hMonitorInfo, const int off wi.cx = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left; wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top; wi.max = (hwnd ? IsZoomed(hwnd) : false) || (wndpl.flags & WPF_RESTORETOMAXIMIZED); - wi.zoom = hwnd ? SciCall_GetZoom() : 100; + wi.zoom = hwnd ? NP3_GetZoomPercent() : NP3_DEFAULT_ZOOM; wi.dpi = Scintilla_GetWindowDPI(hwnd); if (bFullVisible) { diff --git a/src/Notepad3.c b/src/Notepad3.c index 5d9bffbb2..f40753008 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -127,6 +127,9 @@ HPATHL g_tchToolbarBitmapDisabled = NULL; WCHAR Default_PreferredLanguageLocaleName[LOCALE_NAME_MAX_LENGTH + 1] = { L'\0' }; +// zoom conversion helper (forward declaration) +static int ZoomPercentToSciLevel(int percent); + // ------------------------------------ HPATHL s_hpthRelaunchElevatedFile = NULL; @@ -639,6 +642,7 @@ static void _InitGlobals() Globals.iWhiteSpaceSize = 2; Globals.iCaretOutLineFrameSize = 0; + Globals.iZoomPercent = NP3_DEFAULT_ZOOM; Globals.DOSEncoding = CPI_NONE; Globals.bZeroBasedColumnIndex = false; @@ -2192,6 +2196,11 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case WM_MOUSEWHEEL: if (wParam & MK_CONTROL) { + if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) { + NP3_ZoomIn(); + } else if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) { + NP3_ZoomOut(); + } ShowZoomCallTip(); } else if (wParam & MK_RBUTTON) { // Hold RIGHT MOUSE BUTTON and SCROLL to cycle through UNDO history @@ -2728,7 +2737,7 @@ LRESULT MsgCreate(HWND hwnd, WPARAM wParam,LPARAM lParam) Encoding_Current(Settings.DefaultEncoding); - SciCall_SetZoom(g_IniWinInfo.zoom ? g_IniWinInfo.zoom : 100); + NP3_ApplyZoom(g_IniWinInfo.zoom ? g_IniWinInfo.zoom : NP3_DEFAULT_ZOOM); return 0LL; } @@ -6217,19 +6226,19 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) break; case IDM_VIEW_ZOOMIN: { - SciCall_ZoomIn(); + NP3_ZoomIn(); ShowZoomCallTip(); } break; case IDM_VIEW_ZOOMOUT: { - SciCall_ZoomOut(); + NP3_ZoomOut(); ShowZoomCallTip(); } break; case IDM_VIEW_RESETZOOM: { - SciCall_SetZoom(100); + NP3_ApplyZoom(NP3_DEFAULT_ZOOM); ShowZoomCallTip(); } break; @@ -8960,8 +8969,8 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn) case SCN_ZOOM: - SciCall_SetWhiteSpaceSize(MulDiv(Globals.iWhiteSpaceSize, SciCall_GetZoom(), 100)); - SciCall_SetCaretLineFrame(MulDiv(Globals.iCaretOutLineFrameSize, SciCall_GetZoom(), 100)); + SciCall_SetWhiteSpaceSize(MulDiv(Globals.iWhiteSpaceSize, Globals.iZoomPercent, 100)); + SciCall_SetCaretLineFrame(MulDiv(Globals.iCaretOutLineFrameSize, Globals.iZoomPercent, 100)); UpdateToolbar(); UpdateMargins(true); break; @@ -9903,10 +9912,10 @@ static void _UpdateToolbarDelayed() EnableTool(Globals.hwndToolbar, IDT_VIEW_TOGGLE_VIEW, b2 && IsFocusedViewAllowed()); CheckTool(Globals.hwndToolbar, IDT_VIEW_TOGGLE_VIEW, tv); - int const zoom = SciCall_GetZoom(); - CheckTool(Globals.hwndToolbar, IDT_VIEW_ZOOMIN, (zoom > 100)); - CheckTool(Globals.hwndToolbar, IDT_VIEW_RESETZOOM, (zoom == 100)); - CheckTool(Globals.hwndToolbar, IDT_VIEW_ZOOMOUT, (zoom < 100)); + int const zoom = NP3_GetZoomPercent(); + CheckTool(Globals.hwndToolbar, IDT_VIEW_ZOOMIN, (zoom > NP3_DEFAULT_ZOOM)); + CheckTool(Globals.hwndToolbar, IDT_VIEW_RESETZOOM, (zoom == NP3_DEFAULT_ZOOM)); + CheckTool(Globals.hwndToolbar, IDT_VIEW_ZOOMOUT, (zoom < NP3_DEFAULT_ZOOM)); } @@ -10906,7 +10915,7 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags, const DocP UpdateToolbar(); UpdateMargins(true); - if (SciCall_GetZoom() != 100) { + if (NP3_GetZoomPercent() != NP3_DEFAULT_ZOOM) { ShowZoomCallTip(); } @@ -11156,7 +11165,7 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags, const DocP } UpdateMargins(true); - if (SciCall_GetZoom() != 100) { + if (NP3_GetZoomPercent() != NP3_DEFAULT_ZOOM) { ShowZoomCallTip(); } UpdateToolbar_Now(Globals.hwndMain); @@ -12041,6 +12050,68 @@ void ResetMouseDWellTime() SciCall_SetMouseDWellTime(500); // needed for "Mouse cursor vanish handling (hide while typing)" } +//============================================================================= +// +// NP3 Zoom Helpers — percentage-based zoom with Scintilla's additive zoom API +// +// Scintilla zoom is additive: sizeZoomed = fontSize + zoomLevel * FontSizeMultiplier +// NP3 displays percentage (100% = normal). Conversion uses GLOBAL_INITIAL_FONTSIZE. +// + +static int ZoomPercentToSciLevel(int percent) +{ + // zoomLevel = baseFontSizeSM * (percent - 100) / 10000 + // where baseFontSizeSM = GLOBAL_INITIAL_FONTSIZE * 100 (FontSizeMultiplier units) + __int64 const raw = (__int64)NP3_ZOOM_BASE_FONT_SIZE * (percent - 100); + return (int)((raw >= 0) ? (raw + 5000) / 10000 : (raw - 5000) / 10000); +} + +void NP3_ApplyZoom(int percent) +{ + percent = clampi(percent, NP3_MIN_ZOOM_PERCENT, NP3_MAX_ZOOM_PERCENT); + Globals.iZoomPercent = percent; + SciCall_SetZoom(ZoomPercentToSciLevel(percent)); +} + +void NP3_ZoomIn() +{ + int const curLevel = SciCall_GetZoom(); + int percent = Globals.iZoomPercent; + if (percent < 200) { + percent += 10; + } else if (percent < 500) { + percent += 25; + } else { + percent += 50; + } + percent = min_i(percent, NP3_MAX_ZOOM_PERCENT); + int newLevel = ZoomPercentToSciLevel(percent); + if (newLevel <= curLevel) { + newLevel = curLevel + 1; + } + Globals.iZoomPercent = percent; + SciCall_SetZoom(newLevel); +} + +void NP3_ZoomOut() +{ + int const curLevel = SciCall_GetZoom(); + int percent = Globals.iZoomPercent; + percent -= 10; + percent = max_i(percent, NP3_MIN_ZOOM_PERCENT); + int newLevel = ZoomPercentToSciLevel(percent); + if (newLevel >= curLevel) { + newLevel = curLevel - 1; + } + Globals.iZoomPercent = percent; + SciCall_SetZoom(newLevel); +} + +int NP3_GetZoomPercent() +{ + return Globals.iZoomPercent; +} + //============================================================================= // // ShowZoomCallTip() @@ -12051,7 +12122,7 @@ void ShowZoomCallTip() int const delayClr = Settings2.ZoomTooltipTimeout; if (delayClr >= (_MQ_TIMER_CYCLE << 3)) { - StringCchPrintfA(chToolTip, COUNTOF(chToolTip), "Zoom: %i%%", SciCall_GetZoom()); + StringCchPrintfA(chToolTip, COUNTOF(chToolTip), "Zoom: %i%%", NP3_GetZoomPercent()); DocPos const iPos = SciCall_PositionFromLine(SciCall_GetFirstVisibleLine()); diff --git a/src/Notepad3.h b/src/Notepad3.h index 568c79d13..28d6b12a0 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -95,6 +95,11 @@ bool CheckAutoLoadMostRecent(); void ShowZoomCallTip(); void ShowWrapAroundCallTip(bool forwardSearch); +void NP3_ZoomIn(); +void NP3_ZoomOut(); +void NP3_ApplyZoom(int percent); +int NP3_GetZoomPercent(); + void MarkAllOccurrences(const LONG64 delay, const bool bForceClear); void UpdateToolbar(); diff --git a/src/Print.cpp b/src/Print.cpp index 41f404875..5e7e68757 100644 --- a/src/Print.cpp +++ b/src/Print.cpp @@ -358,8 +358,9 @@ extern "C" bool EditPrint(HWND hwnd,LPCWSTR pszDocTitle,LPCWSTR pszPageFormat) SendMessage(hwnd,SCI_SETPRINTCOLOURMODE,printColorModes[Settings.PrintColorMode],0); //SendMessage(hwnd, SCI_SETPRINTWRAPMODE, SC_WRAP_WORD, 0); // default: SC_WRAP_WORD - // Set print magnification... - SendMessage(hwnd, SCI_SETPRINTMAGNIFICATION, (WPARAM)Settings.PrintZoom, 0); + // Set print magnification (convert NP3 percent to Scintilla additive points) + int const printZoomLevel = (int)(((__int64)NP3_ZOOM_BASE_FONT_SIZE * (Settings.PrintZoom - 100) + 5000) / 10000); + SendMessage(hwnd, SCI_SETPRINTMAGNIFICATION, (WPARAM)printZoomLevel, 0); DocPos const lengthDocMax = SciCall_GetTextLength(); DocPos lengthDoc = lengthDocMax; @@ -559,7 +560,7 @@ static UINT_PTR CALLBACK _LPSetupHookProc(HWND hwnd, UINT uiMsg, WPARAM wParam, UDACCEL const acc[1] = { { 0, 10 } }; SendDlgItemMessage(hwnd, 30, EM_LIMITTEXT, 32, 0); SendDlgItemMessage(hwnd, 31, UDM_SETACCEL, 1, (WPARAM)acc); - SendDlgItemMessage(hwnd, 31, UDM_SETRANGE32, SC_MIN_ZOOM_LEVEL, SC_MAX_ZOOM_LEVEL); + SendDlgItemMessage(hwnd, 31, UDM_SETRANGE32, NP3_MIN_ZOOM_PERCENT, NP3_MAX_ZOOM_PERCENT); SendDlgItemMessage(hwnd, 31, UDM_SETPOS32, 0, Settings.PrintZoom); // Set header options diff --git a/src/Styles.c b/src/Styles.c index e7624dbae..29a8ec231 100644 --- a/src/Styles.c +++ b/src/Styles.c @@ -1570,7 +1570,7 @@ void Style_SetLexer(HWND hwnd, PEDITLEXER pLexNew) } Globals.iWhiteSpaceSize = iValue; //SciCall_SetWhiteSpaceSize(iValue); - SciCall_SetWhiteSpaceSize(MulDiv(Globals.iWhiteSpaceSize, SciCall_GetZoom(), 100)); // needs update on zoom + SciCall_SetWhiteSpaceSize(MulDiv(Globals.iWhiteSpaceSize, NP3_GetZoomPercent(), 100)); // needs update on zoom // whitespace colors rgb = RGB(0, 0, 0); @@ -2087,7 +2087,7 @@ void Style_HighlightCurrentLine(HWND hwnd, int iHiLitCurLn) iFrameSize = max_i(1, ScaleIntToDPI(hwnd, iFrameSize)); Globals.iCaretOutLineFrameSize = iFrameSize; // SciCall_SetCaretLineFrame(iFrameSize); - SciCall_SetCaretLineFrame(MulDiv(Globals.iCaretOutLineFrameSize, SciCall_GetZoom(), 100)); // needs update on zoom + SciCall_SetCaretLineFrame(MulDiv(Globals.iCaretOutLineFrameSize, NP3_GetZoomPercent(), 100)); // needs update on zoom } else { SciCall_SetCaretLineFrame(0); diff --git a/src/TypeDefs.h b/src/TypeDefs.h index 6d77e0ee7..d95267fd0 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -249,6 +249,13 @@ typedef enum STATUS_SECTOR_T { #define GLOBAL_INITIAL_FONTSIZE 11.0f +// NP3 zoom constants (percentage-based, 100 = normal) +#define NP3_MIN_ZOOM_PERCENT 10 +#define NP3_MAX_ZOOM_PERCENT 1000 +#define NP3_DEFAULT_ZOOM 100 +// Base font size in Scintilla FontSizeMultiplier units (points * 100) for zoom conversion +#define NP3_ZOOM_BASE_FONT_SIZE ((int)(GLOBAL_INITIAL_FONTSIZE * 100)) + // -------------------------------------------------------------------------- // |- len -| @@ -523,6 +530,7 @@ typedef struct GLOBALS_T { int iWhiteSpaceSize; int iCaretOutLineFrameSize; + int iZoomPercent; bool bMinimizedToTray; bool bZeroBasedColumnIndex; From c438a11619e1c1c6aa0044e169970e88e82351f9 Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Fri, 20 Feb 2026 17:43:48 +0100 Subject: [PATCH 3/3] chore: Copilot update Readme.md --- Readme.md | 666 +++++++------------------------------------ doc/Configuration.md | 485 +++++++++++++++++++++++++++++++ 2 files changed, 590 insertions(+), 561 deletions(-) create mode 100644 doc/Configuration.md diff --git a/Readme.md b/Readme.md index add4bbb32..f91c527e9 100644 --- a/Readme.md +++ b/Readme.md @@ -1,613 +1,157 @@ # Notepad3 -Notepad3 is free and open source. Your support helps keep development active. +**A fast, lightweight, Scintilla-based text editor for Windows** -[![Sponsor](https://img.shields.io/github/sponsors/rizonesoft?style=flat-square&logo=github)](https://github.com/sponsors/rizonesoft) -[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square&logo=paypal)](https://www.paypal.com/donate/?hosted_button_id=7UGGCSDUZJPFE) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause) - -### Build Status -Continuous integration ensures code quality across compilers and platforms. - -[![AppVeyor](https://img.shields.io/appveyor/ci/rizonesoft/notepad3/master.svg?style=flat-square&label=AppVeyor)](https://ci.appveyor.com/project/rizonesoft/notepad3/branch/master) [![CI](https://img.shields.io/github/actions/workflow/status/rizonesoft/Notepad3/build.yml?style=flat-square&label=CI)](https://github.com/rizonesoft/Notepad3/actions/workflows/build.yml) -[![Latest Release](https://img.shields.io/github/v/release/rizonesoft/Notepad3?style=flat-square&label=Release&color=0e7490)](https://rizonesoft.com/downloads/notepad3/) +[![AppVeyor](https://img.shields.io/appveyor/ci/rizonesoft/notepad3/master.svg?style=flat-square&label=AppVeyor)](https://ci.appveyor.com/project/rizonesoft/notepad3/branch/master) +[![Release](https://img.shields.io/github/v/release/rizonesoft/Notepad3?style=flat-square&label=Release&color=0e7490)](https://rizonesoft.com/downloads/notepad3/) [![Nightly](https://img.shields.io/github/v/release/rizonesoft/Notepad3?include_prereleases&style=flat-square&label=Nightly&color=6e40c9)](https://github.com/rizonesoft/Notepad3/releases) -### Tech Stack -Built with modern C++ on the powerful Scintilla editing component. - -[![Windows](https://img.shields.io/badge/Platform-Windows-0078D6?style=flat-square&logo=windows)](https://rizonesoft.com/downloads/notepad3/) -[![C++](https://img.shields.io/badge/Language-C%2B%2B-00599C?style=flat-square&logo=cplusplus)](https://github.com/rizonesoft/Notepad3) -[![Scintilla](https://img.shields.io/badge/Editor-Scintilla-4B8BBE?style=flat-square)](https://www.scintilla.org/) -[![Architecture](https://img.shields.io/badge/Arch-x86%20%7C%20x64%20%7C%20x64--AVX2%20%7C%20ARM64-informational?style=flat-square)](https://rizonesoft.com/downloads/notepad3/) - -Notepad3 is a fast and light-weight Scintilla-based text editor with syntax highlighting. It has a small memory footprint, but is powerful enough to handle most programming jobs. [Download Notepad3 here](https://rizonesoft.com/downloads/notepad3). - -> *Notepad3 is based on code from Florian Balmer's Notepad2 and XhmikosR's Notepad2-mod. MiniPath is based on code from Florian Balmer's metapath.* - -## Important links! -* Download page - https://rizonesoft.com/downloads/notepad3 -* Latest changelog (release notes) - https://rizonesoft.com/downloads/notepad3/update -* Full changelog (all versions/builds) - [Notepad3 - Full Changelog](https://raw.githubusercontent.com/rizonesoft/Notepad3/master/Build/Changes.txt) -* Documentation - https://rizonesoft.com/documents/notepad3 - -## Rizonesoft Support - -* **[GET IN TOUCH](https://rizonesoft.com/contact-us)** -* **Premium Support** - On Rizonesoft, support is free and we will assist you the best we can. Please be patient when contacting us; there are mainly volunteers working on Rizonesoft projects, and time is a precious commodity. - -## Changes compared to Flo's official [Notepad2](https://www.flos-freeware.ch/notepad2.html) (made in [Notepad2-mod](https://xhmikosr.github.io/notepad2-mod/)): - -* Code folding -* Support for bookmarks -* Option to mark all occurrences of a word -* Updated Scintilla component -* Word auto-completion -* Syntax highlighting support for AutoHotkey (AHK), AutoIt3, AviSynth, Bash, CMake, CoffeeScript, - Inno Setup, LaTeX, Lua, Markdown, NSIS, Ruby, Tcl, YAML and VHDL scripts. -* Improved support for NFO ANSI art -* Other various minor changes and tweaks - -## Changes compared to the Notepad2-mod fork: - -* Additional syntax highlighting support for Awk, D, golang, MATLAB -* Regular Expression search engine ([Oniguruma](https://github.com/kkos/oniguruma)) -* New toolbar icons based on Yusuke Kamiyaman's Fugue Icons (purchased by [Rizonesoft](https://rizonesoft.com)) -* Hyperlink hotspot highlighting (single-click Open in Browser (Ctrl) / Load in Editor (Alt) -* Syntax highlighting support for D Source Script, Go Source Script, JSON, Makefiles, MATLAB, Nim Source Code, Power Shell Script, Resource Script, Shell Script -* New program icon and other small cosmetic changes -* In-App support for AES-256 Rijndael encryption/decryption of files (incl. external command line tool for batch processing) -* Virtual space rectangular selection box (Alt-key down) -* High-DPI awareness, including high definition toolbar icons -* Undo/Redo preserves selection -* File history preserves caret position (optional) and remembers encoding of file -* Accelerated word navigation -* Preserve caret position of items in file history -* Count occurrences of a marked selection or word -* Count and mark occurrences of matching search/find expression -* Visual Studio style copy/paste current line (no selection) -* Insert GUIDs -* Dropped support for Windows XP -* Other various minor changes, tweaks, and bugfixes - -## Supported Operating Systems: - -* Windows 7, 8, 8.1, 10, and 11 (both 32-bit and 64-bit) - -
- -# References - -Seen on Nsane Forums: [Notepad3 is an advanced text editor...](https://www.nsaneforums.com/topic/382910-guidereview-notepad3-is-an-advanced-text-editor-that-supports-many-programming-languages/), a review of **Notepad3** posted by the moderator [Karston](https://www.nsaneforums.com/profile/12756-karlston/) at [nsane.forums](https://www.nsaneforums.com/). - -**Notepad3's review**: **[Notepad3 is an advanced text editor that supports many programming languages](https://www.ghacks.net/2020/08/11/notepad3-is-an-advanced-text-editor-that-supports-many-programming-languages/)**. - -
- -# **Notepad3 Settings (Notepad3.ini)** - - -## **`[Notepad3]`** - -This section can be used to redirect to a settings file which will be used by Notepad3. -If a non-elevated user is not allowed to write to the program directory of Notepad3.exe, -the side-by-side Notepad3.ini can point to a place where the user is allowed to write their settings, -for example: - -`Notepad3.ini=%APPDATA%\Rizonesoft\Notepad3\Notepad3.ini` - -or a to have user-specific settings: - -`Notepad3.ini=%WINDIR%\Notepad3-%USERNAME%.ini` - - -## **`[Settings]`** - -These settings are read and written by Notepad3’s user interface. -For example, all Menu ? Settings will go here. - -#### `SettingsVersion=5` - -#### `Favorites=%APPDATA%\Rizonesoft\Notepad3\Favorites\` - - -## **`[Settings2]`** - -This section offers some advanced Notepad3 program settings, and can only be edited manually. -Press Ctrl+F7 to open the Notepad3 ini-file. Most changes only take effect upon restarting Notepad3. - -#### `PreferredLanguageLocaleName=en-US` - -The default value for the already supported languages is defined by the: “OS language setting”. -- The fallback is: “en-US”. - -##### Available languages: +[Website](https://rizonesoft.com/downloads/notepad3/) · [Downloads](https://github.com/rizonesoft/Notepad3/releases) · [Documentation](https://rizonesoft.com/documents/notepad3/) · [Changelog](https://rizonesoft.com/downloads/notepad3/update) · [Sponsor](https://github.com/sponsors/rizonesoft) -``` -English/United States (en-US) (internal default) -Afrikaans/South Africa (af-ZA) -Belarusian/Belarus (be-BY) -German/Germany (de-DE) -Greek/Greece (el-GR) -English/United Kingdom (en-GB) -Spanish/Spain (es-ES) -French/France (fr-FR) -Hindi/India (hi-IN) -Hungarian/Hungary (hu-HU) -Indonesian/Indonesia (id-ID) -Italian/Italy (it-IT) -Japanese/Japan (ja-JP) -Korean/Korea (ko-KR) -Dutch/Netherlands (nl-NL) -Polish/Poland (pl-PL) -Portuguese/Brazil (pt-BR) -Portuguese/Portugal (pt-PT) -Russian/Russia (ru/RU) -Slovak/Slovakia (sk-SK) -Swedish/Sweden (sv-SE) -Turkish/Turkey (tr-TR) -Vietnamese/Vietnam (vi-VN) -Chinese Simplified/China (zh-CN) -Chinese Traditional/Taiwan (zh-TW) -``` - -#### `IMEInteraction=0` - -#### `DateTimeFormat=` - -- (-> (Locale dependent short format) - -#### `DateTimeLongFormat=` - -- (-> (Locale dependent long format) - -Specify the short/long date and time formats. This is the format parameter passed to -the `strftime()` function. -Note that the locale will be set to English (because of the English Visual C++ Run-time -Library used by Notepad3). - -#### `TimeStampRegEx=` - -- (-> \$Date:[^\$]+\$) (Find-Pattern to Update Stamps) - -#### `TimeStampFormat=` - -- (-> \\$Date:[^\\$]+\\$ | $Date: %Y/%m/%d %H:%M:%S $ -- (-> $Date: %s $) (Print format should fit to TimeStampRegEx) - -This parameter is used as a regex pattern to match time-stamps which will be updated to -current date-time by `Shift+F5`, e.g. `$Date: 2018/04/26 00:52:39 $` - -- Default `DateTime` formats are: - 1. SHORT: `[Settings2] DateTimeFormat=` (empty) - Notepad3's language locale short '