Skip to content

Commit

Permalink
Change for DirectWrite non-integer pixel widths, part 3: miscellaneou…
Browse files Browse the repository at this point in the history
…s cleanup and a fix to delete processing; plus some simplification of the new NPPN_GLOBALMOD code and some reorganization of how font size changes are managed
  • Loading branch information
Coises committed Feb 22, 2024
1 parent 201bddb commit f89d0e2
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 43 deletions.
38 changes: 16 additions & 22 deletions src/ColumnsPlusPlus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,15 @@ bool ElasticProgressInfo::setTabstops(bool stepless) {


void ColumnsPlusPlusData::analyzeTabstops(DocumentData& dd) {
dd.elasticAnalysisRequired = false;
dd.deleteWithoutLayoutChange = false;
dd.width24b = sci.TextWidth(STYLE_DEFAULT, " ");
dd.width24d = sci.TextWidth(STYLE_DEFAULT, "123456789012345678901234");
dd.width24w = sci.TextWidth(STYLE_DEFAULT, "WWWWWWWWWWWWWWWWWWWWWWWW");
dd.assumeMonospace = dd.settings.monospace == ElasticTabsProfile::MonospaceBest ? guessMonospaced()
: dd.settings.monospace == ElasticTabsProfile::MonospaceAlways;
int ccsym = settings.monospaceNoMnemonics && dd.assumeMonospace ? '!' : 0;
if (sci.ControlCharSymbol() != ccsym) sci.SetControlCharSymbol(ccsym);
ElasticProgressInfo epi(*this, dd);
epi.isAnalyze = true;
epi.firstNeeded = 0;
Expand All @@ -272,8 +281,6 @@ void ColumnsPlusPlusData::analyzeTabstops(DocumentData& dd) {

bool ElasticProgressInfo::analyzeTabstops() {
auto& sci = data.sci;
dd.elasticAnalysisRequired = false;
dd.deleteWithoutLayoutChange = false;
const Scintilla::Line firstToProcess = step * stepSize;
const Scintilla::Line lastToProcess = std::min(lastNeeded, firstToProcess + stepSize - 1);
if (!step) dd.tabLayouts.clear();
Expand Down Expand Up @@ -414,7 +421,7 @@ void ColumnsPlusPlusData::scnModified(const Scintilla::NotificationData* scnp) {
int width;
if (findTabLayoutBlock(ctd, scnp->position, scnp->length, tlb, width)) {
width += sci.TextWidth(STYLE_DEFAULT, std::string(ctd.settings.minimumSpaceBetweenColumns, ' ').data());
if (!tlb || width < tlb->width) {
if (!tlb || width < tlb->width - 1) /* a one-pixel error is possible with DirectWrite and monospace font optimization */ {
ctd.deleteWithoutLayoutChange = true;
ctd.deleteWithoutLayoutChangePosition = scnp->position;
ctd.deleteWithoutLayoutChangeLength = scnp->length;
Expand All @@ -441,11 +448,7 @@ void ColumnsPlusPlusData::scnUpdateUI(const Scintilla::NotificationData* scnp) {
if (Scintilla::FlagSet(scnp->updated, Scintilla::Update::Selection)) syncFindButton();
if (!ddp->settings.elasticEnabled) return;
ddp->deleteWithoutLayoutChange = false;
if (fontSpacingChange(*ddp)) {
setSpacing(*ddp);
analyzeTabstops(*ddp);
}
else if (ddp->elasticAnalysisRequired) analyzeTabstops(*ddp);
if (ddp->elasticAnalysisRequired || fontSpacingChange(*ddp)) analyzeTabstops(*ddp);
if (Scintilla::FlagSet(scnp->updated, Scintilla::Update::Selection)) reselectRectangularSelectionAndControlCharSymbol(*ddp, false);
setTabstops(*ddp);
}
Expand All @@ -455,7 +458,6 @@ void ColumnsPlusPlusData::scnZoom(const Scintilla::NotificationData* scnp) {
DocumentData* ddp = getDocument(scnp);
if (!ddp || !ddp->settings.elasticEnabled) return;
ddp->deleteWithoutLayoutChange = false;
setSpacing(*ddp);
analyzeTabstops(*ddp);
setTabstops(*ddp);
}
Expand Down Expand Up @@ -496,7 +498,6 @@ void ColumnsPlusPlusData::bufferActivated() {
}
if (settings.overrideTabSize) sci.SetTabWidth(settings.minimumOrLeadingTabSize);
if (isNewDocument) {
setSpacing(dd);
analyzeTabstops(dd);
setTabstops(dd);
}
Expand Down Expand Up @@ -526,17 +527,11 @@ void ColumnsPlusPlusData::modifyAll(const NMHDR* nmhdr) {
position &= 0x3FFFFFFF;
intptr_t index = SendMessage(nppData._nppHandle, NPPM_GETCURRENTDOCINDEX, 0, secondary);
if (index < 0) return;
if (position == index) /* buffer is visible (notification happens, or at least can happen, after scnUpdateUI due to changes) */ {
activeScintilla = secondary ? nppData._scintillaSecondHandle : nppData._scintillaMainHandle;
pointerScintilla = SendMessage(activeScintilla, static_cast<UINT>(Scintilla::Message::GetDirectPointer), 0, 0);
sci.SetFnPtr(directStatusScintilla, pointerScintilla);
sci.SetStatus(Scintilla::Status::Ok);
void* docptr = sci.DocPointer();
if (!documents.contains(docptr)) return;
DocumentData& dd = documents[docptr];
if (fontSpacingChange(dd)) setSpacing(dd);
analyzeTabstops(dd);
setTabstops(dd);
if (position == index) /* buffer is visible */ {
DocumentData* ddp = getDocument(secondary ? nppData._scintillaSecondHandle : nppData._scintillaMainHandle);
if (!ddp) return;
analyzeTabstops(*ddp);
setTabstops(*ddp);
return;
}
for (auto i = documents.begin(); i != documents.end(); ++i) if (i->second.buffer == bufferID) {
Expand All @@ -557,7 +552,6 @@ void ColumnsPlusPlusData::toggleElasticEnabled() {
sci.SetTabWidth(settings.minimumOrLeadingTabSize);
}
sci.SetTabIndents(0);
setSpacing(*ddp);
analyzeTabstops(*ddp);
setTabstops(*ddp);
} else {
Expand Down
39 changes: 19 additions & 20 deletions src/ColumnsPlusPlus.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,9 @@ class DocumentData {
DocumentDataSettings settings;
std::vector<TabLayoutBlock> tabLayouts;
UINT_PTR buffer; // identifier used by Notepad++ messages and notifications
int blankWidth = 0; // the blank width at which tabLayouts were calculated; if this changes, full analysis is required
int width24b = 0; // the widths of 24 blanks, 24 digits and 24 capital W letters
int width24d = 0; // at which tabLayouts were calculated;
int width24w = 0; // if these values change, full analysis is required
int tabOriginal; // set when buffer activated, used for restore when elasticTabsEnabled or overrideTabSize turned off
bool elasticAnalysisRequired = false;
bool deleteWithoutLayoutChange = false;
Expand Down Expand Up @@ -398,8 +400,8 @@ class ColumnsPlusPlusData {
return &dd;
}

DocumentData* getDocument(const Scintilla::NotificationData* scnp) {
activeScintilla = reinterpret_cast<HWND>(scnp->nmhdr.hwndFrom);
DocumentData* getDocument(HWND scintillaHandle) {
activeScintilla = scintillaHandle;
pointerScintilla = SendMessage(activeScintilla, static_cast<UINT>(Scintilla::Message::GetDirectPointer), 0, 0);
sci.SetFnPtr(directStatusScintilla, pointerScintilla);
sci.SetStatus(Scintilla::Status::Ok); // C-interface code can ignore an error status, which would cause the C++ interface to raise an exception
Expand All @@ -408,33 +410,30 @@ class ColumnsPlusPlusData {
return &documents[docptr];
}

DocumentData* getDocument(const Scintilla::NotificationData* scnp) { return getDocument(reinterpret_cast<HWND>(scnp->nmhdr.hwndFrom)); }

RectangularSelection getRectangularSelection();

bool fontSpacingChange(DocumentData& dd) {
int width = sci.TextWidth(STYLE_DEFAULT, " ");
if (width != dd.blankWidth) return true;
if (dd.settings.monospace != ElasticTabsProfile::MonospaceBest) return false;
return dd.assumeMonospace != guessMonospaced(width);
if (dd.width24b != sci.TextWidth(STYLE_DEFAULT, " ")) return true;
if (dd.width24d != sci.TextWidth(STYLE_DEFAULT, "123456789012345678901234")) return true;
if (dd.width24w != sci.TextWidth(STYLE_DEFAULT, "WWWWWWWWWWWWWWWWWWWWWWWW")) return true;
return false;
}

bool guessMonospaced(int width = 0) {
if (!width) width = sci.TextWidth(STYLE_DEFAULT, " ");
if (sci.TextWidth(STYLE_DEFAULT, "W") != width) return false;
bool guessMonospaced() {
int width24b = sci.TextWidth(STYLE_DEFAULT, " ");
int width24w = sci.TextWidth(STYLE_DEFAULT, "WWWWWWWWWWWWWWWWWWWWWWWW");
if (width24b != width24w) return false;
for (int style = 0; style < STYLE_DEFAULT; ++style)
if (sci.TextWidth(style, "W") != width || sci.TextWidth(style, " ") != width) return false;
if ( sci.TextWidth(style, "WWWWWWWWWWWWWWWWWWWWWWWW") != width24b
|| sci.TextWidth(style, " ") != width24b) return false;
for (int style = STYLE_LASTPREDEFINED + 1; style < 256; ++style)
if (sci.TextWidth(style, "W") != width || sci.TextWidth(style, " ") != width) return false;
if ( sci.TextWidth(style, "WWWWWWWWWWWWWWWWWWWWWWWW") != width24b
|| sci.TextWidth(style, " ") != width24b) return false;
return true;
}

void setSpacing(DocumentData& dd) {
dd.blankWidth = sci.TextWidth(STYLE_DEFAULT, " ");
dd.assumeMonospace = dd.settings.monospace == ElasticTabsProfile::MonospaceBest ? guessMonospaced(dd.blankWidth)
: dd.settings.monospace == ElasticTabsProfile::MonospaceAlways;
int ccsym = settings.monospaceNoMnemonics && dd.assumeMonospace ? '!' : 0;
if (sci.ControlCharSymbol() != ccsym) sci.SetControlCharSymbol(ccsym);
}

void reselectRectangularSelectionAndControlCharSymbol(DocumentData& dd, bool setControlCharSymbol) {
if (!dd.settings.elasticEnabled) return;
Scintilla::SelectionMode selectionMode = sci.SelectionMode();
Expand Down
1 change: 0 additions & 1 deletion src/Profiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ void ColumnsPlusPlusData::showElasticProfile() {
ddp->settings = settings;
if (settings.elasticEnabled) {
sci.SetTabWidth(settings.overrideTabSize ? settings.minimumOrLeadingTabSize : ddp->tabOriginal);
setSpacing(*ddp);
analyzeTabstops(*ddp);
setTabstops(*ddp);
}
Expand Down

0 comments on commit f89d0e2

Please sign in to comment.