diff options
-rw-r--r-- | src/ContractionState.cxx | 6 | ||||
-rw-r--r-- | src/Editor.cxx | 29 | ||||
-rw-r--r-- | src/LexCPP.cxx | 9 | ||||
-rw-r--r-- | src/PropSet.cxx | 104 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 34 |
5 files changed, 122 insertions, 60 deletions
diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx index 456948900..0b987b81b 100644 --- a/src/ContractionState.cxx +++ b/src/ContractionState.cxx @@ -171,12 +171,6 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible delta += visible ? 1 : -1; lines[line].visible = visible; } - lines[line].displayLine += delta; - } - if (delta != 0) { - for (int line=lineDocEnd+1; line <= linesInDoc; line++) { - lines[line].displayLine += delta; - } } } linesInDisplay += delta; diff --git a/src/Editor.cxx b/src/Editor.cxx index 3cf2c179e..694d4855a 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -734,9 +734,10 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou char styleByte = 0; int styleMask = pdoc->stylingBitsMask; ll.xHighlightGuide = 0; - for (int charInDoc = posLineStart; - charInDoc < posLineEnd && numCharsInLine < LineLayout::maxLineLength - 2; - charInDoc++) { + if (posLineEnd >= (posLineStart + LineLayout::maxLineLength)) { + posLineEnd = posLineStart + LineLayout::maxLineLength - 1; + } + for (int charInDoc=posLineStart; charInDoc<posLineEnd; charInDoc++) { char chDoc = pdoc->CharAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc); if (vstyle.viewEOL || ((chDoc != '\r') && (chDoc != '\n'))) { @@ -772,8 +773,14 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3; } } else { - surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg, - charInLine - startseg + 1, ll.positions + startseg + 1); + int lenSeg = charInLine - startseg + 1; + if ((lenSeg == 1) && (' ' == ll.chars[startseg])) { + // Over half the segments are single characters and of these about half are space characters. + ll.positions[charInLine + 1] = vstyle.styles[ll.styles[charInLine]].spaceWidth; + } else { + surface->MeasureWidths(vstyle.styles[ll.styles[charInLine]].font, ll.chars + startseg, + charInLine - startseg + 1, ll.positions + startseg + 1); + } } for (int posToIncrease = startseg; posToIncrease <= (charInLine + 1); posToIncrease++) { ll.positions[posToIncrease] += startsegx; @@ -1723,10 +1730,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { } } } - if (mh.modificationType & SC_MOD_BEFOREINSERT) { - NotifyNeedShown(mh.position, 0); - } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { - NotifyNeedShown(mh.position, mh.length); + if (cs.LinesDisplayed() < cs.LinesInDoc()) { + // Some lines are hidden so may need shown. + // TODO: check if the modified area is hidden. + if (mh.modificationType & SC_MOD_BEFOREINSERT) { + NotifyNeedShown(mh.position, 0); + } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { + NotifyNeedShown(mh.position, mh.length); + } } if (mh.linesAdded != 0) { diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx index 8e3b7c498..b77468a44 100644 --- a/src/LexCPP.cxx +++ b/src/LexCPP.cxx @@ -19,14 +19,13 @@ static bool classifyWordCpp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { char s[100]; - bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); - bool wordIsUUID = false; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; s[i + 1] = '\0'; } + bool wordIsUUID = false; char chAttr = SCE_C_IDENTIFIER; - if (wordIsNumber) + if (isdigit(s[0]) || (s[0] == '.')) chAttr = SCE_C_NUMBER; else { if (keywords.InList(s)) { @@ -99,7 +98,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo state = SCE_C_UUID; lastWordWasUUID = false; } else { - state = SCE_C_WORD; + state = SCE_C_IDENTIFIER; } } else if (ch == '/' && chNext == '*') { styler.ColourTo(i-1, state); @@ -132,7 +131,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo levelCurrent += (ch == '{') ? 1 : -1; } } - } else if (state == SCE_C_WORD) { + } else if (state == SCE_C_IDENTIFIER) { if (!iswordchar(ch)) { lastWordWasUUID = classifyWordCpp(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_C_DEFAULT; diff --git a/src/PropSet.cxx b/src/PropSet.cxx index 6fc02cb0a..0f2b1bd85 100644 --- a/src/PropSet.cxx +++ b/src/PropSet.cxx @@ -24,6 +24,16 @@ bool EqualCaseInsensitive(const char *a, const char *b) { #endif } +unsigned int HashString(const char *s) { + unsigned int ret = 0; + while (*s) { + ret <<= 4; + ret ^= *s; + s++; + } + return ret; +} + // Get a line of input. If end of line escaped with '\\' then continue reading. static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { bool continuation = true; @@ -56,44 +66,46 @@ static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) { PropSet::PropSet() { superPS = 0; - size = 10; + size = 20; used = 0; - vals = new char * [size]; + properties = new Property[size]; } PropSet::~PropSet() { superPS = 0; Clear(); - delete []vals; + delete []properties; } void PropSet::EnsureCanAddEntry() { - if (used >= size - 2) { - int newsize = size + 10; - char **newvals = new char * [newsize]; + if (used >= size - 1) { + int newsize = size + 20; + Property *newprops = new Property[newsize]; for (int i = 0; i < used; i++) { - newvals[i] = vals[i]; + newprops[i] = properties[i]; } - delete []vals; - vals = newvals; + delete []properties; + properties = newprops; size = newsize; } } void PropSet::Set(const char *key, const char *val) { EnsureCanAddEntry(); - for (int i = 0; i < used; i += 2) { - if (0 == strcmp(vals[i], key)) { + for (int i = 0; i < used; i++) { + if (0 == strcmp(properties[i].key, key)) { // Replace current value - delete [](vals[i + 1]); - vals[i + 1] = StringDup(val); + delete [](properties[i].val); + properties[i].val = StringDup(val); return; } } // Not found - vals[used++] = StringDup(key); - vals[used++] = StringDup(val); + properties[used].hash = HashString(key); + properties[used].key = StringDup(key); + properties[used].val = StringDup(val); + used++; } void PropSet::Set(char *keyval) { @@ -108,9 +120,10 @@ void PropSet::Set(char *keyval) { } SString PropSet::Get(const char *key) { - for (int i = 0; i < used; i += 2) { - if (0 == strcmp(vals[i], key)) { - return vals[i + 1]; + unsigned int hash = HashString(key); + for (int i = 0; i < used; i++) { + if ((hash == properties[i].hash) && (0 == strcmp(properties[i].key, key))) { + return properties[i].val; } } if (superPS) { @@ -121,6 +134,36 @@ SString PropSet::Get(const char *key) { } } +SString PropSet::GetExpanded(const char *key) { + SString val = Get(key); + return Expand(val.c_str()); +} + +SString PropSet::Expand(const char *withvars) { + char *base = StringDup(withvars); + char *cpvar = strstr(base, "$("); + while (cpvar) { + char *cpendvar = strchr(cpvar, ')'); + if (cpendvar) { + int lenvar = cpendvar - cpvar - 2; // Subtract the $() + char *var = StringDup(cpvar+2, lenvar); + SString val = GetExpanded(var); + int newlenbase = strlen(base) + val.length() - lenvar; + char *newbase = new char[newlenbase]; + strncpy(newbase, base, cpvar - base); + strcpy(newbase + (cpvar - base), val.c_str()); + strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1); + delete []var; + delete []base; + base = newbase; + } + cpvar = strstr(base, "$("); + } + SString sret = base; + delete []base; + return sret; +} + int PropSet::GetInt(const char *key, int defaultValue) { SString val = Get(key); if (val.length()) @@ -155,9 +198,9 @@ bool issuffix(const char *target, const char *suffix) { } SString PropSet::GetWild(const char *keybase, const char *filename) { - for (int i = 0; i < used; i += 2) { - if (isprefix(vals[i], keybase)) { - char *orgkeyfile = vals[i] + strlen(keybase); + for (int i = 0; i < used; i++) { + if (isprefix(properties[i].key, keybase)) { + char *orgkeyfile = properties[i].key + strlen(keybase); char *keyfile = NULL; if (strstr(orgkeyfile, "$(") == orgkeyfile) { @@ -184,12 +227,12 @@ SString PropSet::GetWild(const char *keybase, const char *filename) { if (issuffix(filename, keyfile + 1)) { *del = delchr; free(keyptr); - return vals[i + 1]; + return properties[i].val; } } else if (0 == strcmp(keyfile, filename)) { *del = delchr; free(keyptr); - return vals[i + 1]; + return properties[i].val; } if (delchr == '\0') break; @@ -198,8 +241,8 @@ SString PropSet::GetWild(const char *keybase, const char *filename) { } free(keyptr); - if (0 == strcmp(vals[i], keybase)) { - return vals[i + 1]; + if (0 == strcmp(properties[i].key, keybase)) { + return properties[i].val; } } } @@ -218,9 +261,7 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { char *cpendvar = strchr(cpvar, ')'); if (cpendvar) { int lenvar = cpendvar - cpvar - 2; // Subtract the $() - char *var = new char[lenvar + 1]; - strncpy(var, cpvar + 2, lenvar); - var[lenvar] = '\0'; + char *var = StringDup(cpvar+2, lenvar); SString val = GetWild(var, filename); int newlenbase = strlen(base) + val.length() - lenvar; char *newbase = new char[newlenbase]; @@ -240,8 +281,11 @@ SString PropSet::GetNewExpand(const char *keybase, const char *filename) { void PropSet::Clear() { for (int i = 0; i < used; i++) { - delete [](vals[i]); - vals[i] = 0; + properties[i].hash = 0; + delete []properties[i].key; + properties[i].key = 0; + delete []properties[i].val; + properties[i].val = 0; } used = 0; } diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 7cdbc64e6..31419127f 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -345,7 +345,7 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { // i.e. if datazoomed out only class structures are visible, when datazooming in the control // structures appear, then eventually the individual statements...) if (wParam & MK_SHIFT) { - return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); + return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); } // Either SCROLL or ZOOM. We handle the wheel steppings calculation @@ -435,12 +435,12 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { int ret = KeyDown(wParam, Platform::IsKeyDown(VK_SHIFT), Platform::IsKeyDown(VK_CONTROL), false); if (!ret) - return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); + return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); break; } case WM_IME_KEYDOWN: - return DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); + return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); case WM_KEYUP: //Platform::DebugPrintf("S keyup %d %x %x\n",iMessage, wParam, lParam); @@ -537,13 +537,27 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) { return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); case WM_ERASEBKGND: + return 1; // Avoid any background erasure as whole window painted. + + // These are not handled in Scintilla and its faster to dispatch them here. + // Also moves time out to here so profile doesn't count lots of empty message calls. + case WM_MOVE: + case WM_MOUSEACTIVATE: case WM_NCHITTEST: + case WM_NCCALCSIZE: case WM_NCPAINT: + case WM_NCMOUSEMOVE: + case WM_NCLBUTTONDOWN: + case WM_CAPTURECHANGED: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: + case WM_SYSCOMMAND: + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); default: - //return ::DefWindowProc(wMain.GetID(), iMessage, wParam, lParam); - return ScintillaBase::WndProc(iMessage, wParam, lParam); + return ScintillaBase::WndProc(iMessage, wParam, lParam); } return 0l; } @@ -1493,12 +1507,12 @@ LRESULT PASCAL ScintillaWin::CTWndProc( reinterpret_cast<LONG>(pCreate->lpCreateParams)); return 0; } else { - return DefWindowProc(hWnd, iMessage, wParam, lParam); + return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } } else { if (iMessage == WM_DESTROY) { SetWindowLong(hWnd, 0, 0); - return DefWindowProc(hWnd, iMessage, wParam, lParam); + return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } else if (iMessage == WM_PAINT) { PAINTSTRUCT ps; ::BeginPaint(hWnd, &ps); @@ -1509,7 +1523,7 @@ LRESULT PASCAL ScintillaWin::CTWndProc( ::EndPaint(hWnd, &ps); return 0; } else { - return DefWindowProc(hWnd, iMessage, wParam, lParam); + return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } } } @@ -1528,14 +1542,14 @@ LRESULT PASCAL ScintillaWin::SWndProc( SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(sci)); return sci->WndProc(iMessage, wParam, lParam); } else { - return DefWindowProc(hWnd, iMessage, wParam, lParam); + return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } } else { if (iMessage == WM_DESTROY) { sci->Finalise(); delete sci; SetWindowLong(hWnd, 0, 0); - return DefWindowProc(hWnd, iMessage, wParam, lParam); + return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } else { return sci->WndProc(iMessage, wParam, lParam); } |