| 28 skipped lines |
| 29 | U | 29 | U | #include "Document.h" |
|
| 30 | U | 30 | U | #include "Editor.h" |
|
|
| | | 32 | A | /* |
| | | 33 | A | return whether this modification represents an operation that |
| | | 34 | A | may reasonably be deferred (not done now OR [possibly] at all) |
| | | 35 | A | */ |
| | | 36 | A | static bool CanDeferToLastStep(const DocModification& mh) { |
| 21 skipped lines |
| | | 58 | A | && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0 |
| | | 59 | A | && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0 |
| | | 60 | A | && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0; |
| | | 61 | A | } |
| | | 62 | A | |
|
| 33 | U | 64 | U | active(false), on(false), period(500) {} |
|
|
| 19 skipped lines |
|
|
|
| | | 88 | A | styleBitsSet(0), |
|
|
|
| 97 skipped lines |
|
| 158 | U | 190 | U | LineLayoutCache::LineLayoutCache() : |
|
| 159 | U | 191 | U | level(0), length(0), size(0), cache(0), |
|
| 160 | C | allInvalidated(false), styleClock(-1) { | | 192 | C | allInvalidated(false), styleClock(-1), useCount(0) { |
|
|
|
| 2 skipped lines |
|
|
| 168 | U | 200 | U | void LineLayoutCache::Allocate(int length_) { |
|
| | | 201 | A | PLATFORM_ASSERT(cache == NULL); |
| 169 | U | 202 | U | allInvalidated = false; |
|
| 170 | U | 203 | U | length = length_; |
|
|
| 8 skipped lines |
|
|
| 182 | U | 215 | U | void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) { |
|
| | | 216 | A | PLATFORM_ASSERT(useCount == 0); |
| 183 | U | 217 | U | int lengthForLevel = 0; |
|
| 184 | U | 218 | U | if (level == llcCaret) { |
|
| 185 | U | 219 | U | lengthForLevel = 1; |
|
| 4 skipped lines |
|
| 191 | U | 225 | U | if (lengthForLevel > size) { |
|
|
| 193 | R | } else if (lengthForLevel < length) { | | |
| 194 | R | for (int i = lengthForLevel; i < length; i++) { | | |
| 195 | R | delete cache[i]; | | |
| 196 | R | cache[i] = 0; | | |
| 197 | R | } | | |
| 198 | R | } | | |
| 199 | R | if (!cache) { | | |
| 200 | U | 227 | U | Allocate(lengthForLevel); |
|
| | | 228 | A | } else { |
| | | 229 | A | if (lengthForLevel < length) { |
| | | 230 | A | for (int i = lengthForLevel; i < length; i++) { |
| | | 231 | A | delete cache[i]; |
| | | 232 | A | cache[i] = 0; |
| | | 233 | A | } |
| | | 234 | A | } |
| | | 235 | A | length = lengthForLevel; |
|
| | | 237 | A | PLATFORM_ASSERT(length == lengthForLevel); |
| | | 238 | A | PLATFORM_ASSERT(cache != NULL || length == 0); |
|
|
| 204 | U | 241 | U | void LineLayoutCache::Deallocate() { |
|
| | | 242 | A | PLATFORM_ASSERT(useCount == 0); |
| 205 | U | 243 | U | for (int i = 0; i < length; i++) |
|
| 206 | U | 244 | U | delete cache[i]; |
|
|
|
|
| | | 248 | A | size = 0; |
|
|
| 212 | U | 251 | U | void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) { |
|
| 31 skipped lines |
|
| 245 | U | 284 | U | } else if (level == llcPage) { |
|
| 246 | U | 285 | U | if (lineNumber == lineCaret) { |
|
| 247 | C | pos = length; | | 286 | C | pos = 0; |
|
| 249 | C | pos = lineNumber % length; | | 288 | C | pos = 1 + (lineNumber % (length - 1)); |
|
| 251 | U | 290 | U | } else if (level == llcDocument) { |
|
| 252 | U | 291 | U | pos = lineNumber; |
|
|
|
| | | 294 | A | PLATFORM_ASSERT(useCount == 0); |
| 255 | U | 295 | U | if (cache && (pos < length)) { |
|
| 256 | U | 296 | U | if (cache[pos]) { |
|
| 257 | U | 297 | U | if ((cache[pos]->lineNumber != lineNumber) || |
|
| 9 skipped lines |
| 267 | U | 307 | U | cache[pos]->lineNumber = lineNumber; |
|
| 268 | U | 308 | U | cache[pos]->inCache = true; |
|
| 269 | U | 309 | U | ret = cache[pos]; |
|
| | | 310 | A | useCount++; |
|
|
|
| 11 skipped lines |
|
| 285 | U | 326 | U | if (!ll->inCache) { |
|
|
| 287 | C | } | | 328 | C | } else { |
| | | 329 | C | useCount--; |
| | | 330 | C | } |
|
|
|
| 53 skipped lines |
| 344 | U | 387 | U | scrollWidth = 2000; |
|
| 345 | U | 388 | U | verticalScrollBarVisible = true; |
|
| 346 | U | 389 | U | endAtLastLine = true; |
|
| | | 390 | A | caretSticky = false; |
|
| 348 | U | 392 | U | pixmapLine = Surface::Allocate(); |
|
| 349 | U | 393 | U | pixmapSelMargin = Surface::Allocate(); |
|
| 11 skipped lines |
|
|
|
| 364 | C | lengthForEncode = 0; | | 408 | C | lengthForEncode = -1; |
|
| 366 | U | 410 | U | needUpdateUI = true; |
|
| 367 | U | 411 | U | braces[0] = invalidPosition; |
|
| 24 skipped lines |
| 392 | U | 436 | U | wrapVisualStartIndent = 0; |
|
| 393 | U | 437 | U | actualWrapVisualStartIndent = 0; |
|
|
| | | 439 | A | convertPastes = true; |
| | | 440 | A | |
|
|
|
| 22 skipped lines |
| 420 | U | 466 | U | pixmapSelMargin->Release(); |
|
| 421 | U | 467 | U | pixmapSelPattern->Release(); |
|
| 422 | U | 468 | U | pixmapIndentGuide->Release(); |
|
| | | 469 | A | pixmapIndentGuideHighlight->Release(); |
|
|
| 425 | U | 472 | U | void Editor::InvalidateStyleData() { |
|
| 416 skipped lines |
| 842 | U | 889 | U | //wMain.InvalidateAll(); |
|
|
|
| 845 | C | void Editor::RedrawSelMargin() { | | 892 | C | void Editor::RedrawSelMargin(int line) { |
| 846 | U | 893 | U | if (!AbandonPaint()) { |
|
| 847 | U | 894 | U | if (vs.maskInLine) { |
|
|
|
| 850 | U | 897 | U | PRectangle rcSelMargin = GetClientRectangle(); |
|
| 851 | U | 898 | U | rcSelMargin.right = vs.fixedColumnWidth; |
|
| | | 899 | A | if (line != -1) { |
| | | 900 | A | int position = pdoc->LineStart(line); |
| | | 901 | A | PRectangle rcLine = RectangleFromRange(position, position); |
| | | 902 | A | rcSelMargin.top = rcLine.top; |
| | | 903 | A | rcSelMargin.bottom = rcLine.bottom; |
| | | 904 | A | } |
| 852 | U | 905 | U | wMain.InvalidateRectangle(rcSelMargin); |
|
|
|
| 44 skipped lines |
| 899 | U | 952 | U | return Platform::Maximum(currentPos, anchor); |
|
|
|
| | | 955 | A | void Editor::SetRectangularRange() { |
| | | 956 | A | if (selType == selRectangle) { |
| | | 957 | A | xStartSelect = XFromPosition(anchor); |
| | | 958 | A | xEndSelect = XFromPosition(currentPos); |
| | | 959 | A | } |
| | | 960 | A | } |
| | | 961 | A | |
| 902 | U | 962 | U | void Editor::InvalidateSelection(int currentPos_, int anchor_) { |
|
| 903 | U | 963 | U | int firstAffected = anchor; |
|
| 904 | U | 964 | U | if (firstAffected > currentPos) |
|
| 21 skipped lines |
| 926 | U | 986 | U | currentPos = currentPos_; |
|
| 927 | U | 987 | U | anchor = anchor_; |
|
|
| 929 | C | if (selType == selRectangle) { | | |
| 930 | C | xStartSelect = XFromPosition(anchor); | | 989 | C | SetRectangularRange(); |
| 931 | C | xEndSelect = XFromPosition(currentPos); | | |
| 932 | C | } | | |
| 933 | U | 990 | U | ClaimSelection(); |
|
|
|
| 3 skipped lines |
| 939 | U | 996 | U | InvalidateSelection(currentPos_, currentPos_); |
|
| 940 | U | 997 | U | currentPos = currentPos_; |
|
|
| 942 | C | if (selType == selRectangle) { | | |
| 943 | C | xStartSelect = XFromPosition(anchor); | | 999 | C | SetRectangularRange(); |
| 944 | C | xEndSelect = XFromPosition(currentPos); | | |
| 945 | C | } | | |
| 946 | U | 1000 | U | ClaimSelection(); |
|
|
|
| 116 skipped lines |
| 1065 | U | 1119 | U | SetTopLine(topLineNew); |
|
| 1066 | U | 1120 | U | ShowCaretAtCurrentPosition(); |
|
| 1067 | U | 1121 | U | // Perform redraw rather than scroll if many lines would be redrawn anyway. |
|
| | | 1122 | A | #ifndef UNDER_CE |
| 1068 | U | 1123 | U | if (abs(linesToMove) <= 10) { |
|
| 1069 | U | 1124 | U | ScrollText(linesToMove); |
|
|
|
|
| | | 1128 | A | #else |
| | | 1129 | A | Redraw(); |
| | | 1130 | A | #endif |
| 1073 | U | 1131 | U | if (moveThumb) { |
|
| 1074 | U | 1132 | U | SetVerticalScrollPos(); |
|
|
| 796 skipped lines |
| 1872 | U | 1930 | U | posLineEnd = posLineStart + ll->maxLineLength; |
|
|
| 1874 | U | 1932 | U | if (ll->validity == LineLayout::llCheckTextAndStyle) { |
|
| 1875 | C | int lineLength = 0; | | 1933 | C | int lineLength = posLineEnd - posLineStart; |
| | | 1934 | C | if (!vstyle.viewEOL) { |
| 1876 | C | for (int cid = posLineStart; cid < posLineEnd; cid++) { | | 1935 | C | int cid = posLineEnd - 1; |
| 1877 | C | char chDoc = pdoc->CharAt(cid); | | |
| 1878 | C | if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { | | 1936 | C | while ((cid > posLineStart) && IsEOLChar(pdoc->CharAt(cid))) { |
| | | 1937 | C | cid--; |
| 1879 | C | lineLength++; | | 1938 | C | lineLength--; |
|
|
| 1882 | U | 1941 | U | if (lineLength == ll->numCharsInLine) { |
|
| 1883 | R | int numCharsInLine = 0; | | |
| 1884 | U | 1942 | U | // See if chars, styles, indicators, are all the same |
|
| 1885 | U | 1943 | U | bool allSame = true; |
|
| 1886 | U | 1944 | U | const int styleMask = pdoc->stylingBitsMask; |
|
| 1887 | U | 1945 | U | // Check base line layout |
|
| | | 1946 | C | char styleByte = 0; |
| | | 1947 | C | int numCharsInLine = 0; |
| | | 1948 | C | while (numCharsInLine < lineLength) { |
| 1888 | C | for (int charInDoc = posLineStart; allSame && (charInDoc < posLineEnd); charInDoc++) { | | 1949 | C | int charInDoc = numCharsInLine + posLineStart; |
| 1889 | U | 1950 | U | char chDoc = pdoc->CharAt(charInDoc); |
|
| 1890 | C | if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { | | 1951 | C | styleByte = pdoc->StyleAt(charInDoc); |
| | | 1952 | C | allSame = allSame && |
| | | 1953 | C | (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask)); |
| | | 1954 | C | allSame = allSame && |
| 1891 | C | char styleByte = pdoc->StyleAt(charInDoc); | | 1955 | C | (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask)); |
| | | 1956 | C | if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed) |
| 1892 | U | 1957 | U | allSame = allSame && |
|
| 1893 | C | (ll->styles[numCharsInLine] == static_cast<char>(styleByte & styleMask)); | | 1958 | C | (ll->chars[numCharsInLine] == chDoc); |
| | | 1959 | C | else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) |
| 1894 | U | 1960 | U | allSame = allSame && |
|
| 1895 | C | (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask)); | | |
| 1896 | C | if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper) | | |
| 1897 | C | allSame = allSame && | | |
| 1898 | C | (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); | | 1961 | C | (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc))); |
| 1899 | C | else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) | | 1962 | C | else// Style::caseUpper |
| 1900 | C | allSame = allSame && | | 1963 | C | allSame = allSame && |
| 1901 | C | (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc))); | | 1964 | C | (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); |
| 1902 | C | else | | |
| 1903 | C | allSame = allSame && | | |
| 1904 | C | (ll->chars[numCharsInLine] == chDoc); | | |
| 1905 | C | numCharsInLine++; | | 1965 | C | numCharsInLine++; |
| 1906 | C | } | | |
|
| | | 1967 | A | allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled |
| 1908 | U | 1968 | U | if (allSame) { |
|
| 1909 | U | 1969 | U | ll->validity = LineLayout::llPositions; |
|
|
| 18 skipped lines |
|
| 1930 | U | 1990 | U | char styleByte = 0; |
|
| 1931 | U | 1991 | U | int styleMask = pdoc->stylingBitsMask; |
|
| | | 1992 | A | ll->styleBitsSet = 0; |
| 1932 | U | 1993 | U | // Fill base line layout |
|
| 1933 | U | 1994 | U | for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) { |
|
| 1934 | U | 1995 | U | char chDoc = pdoc->CharAt(charInDoc); |
|
| 1935 | U | 1996 | U | styleByte = pdoc->StyleAt(charInDoc); |
|
| | | 1997 | A | ll->styleBitsSet |= styleByte; |
| 1936 | U | 1998 | U | if (vstyle.viewEOL || (!IsEOLChar(chDoc))) { |
|
| 1937 | U | 1999 | U | ll->chars[numCharsInLine] = chDoc; |
|
| 1938 | U | 2000 | U | ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask); |
|
| 20 skipped lines |
| 1959 | U | 2021 | U | bool lastSegItalics = false; |
|
| 1960 | U | 2022 | U | Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font; |
|
|
| | | 2024 | A | int ctrlCharWidth[32] = {0}; |
| 1962 | U | 2025 | U | bool isControlNext = IsControlCharacter(ll->chars[0]); |
|
| 1963 | U | 2026 | U | for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) { |
|
| 1964 | U | 2027 | U | bool isControl = isControlNext; |
|
| 7 skipped lines |
| 1972 | U | 2035 | U | ll->positions[charInLine + 1] = ((((startsegx + 2) / |
|
| 1973 | U | 2036 | U | tabWidth) + 1) * tabWidth) - startsegx; |
|
| 1974 | U | 2037 | U | } else if (controlCharSymbol < 32) { |
|
| | | 2038 | C | if (ctrlCharWidth[ll->chars[charInLine]] == 0) { |
| 1975 | C | const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]); | | 2039 | C | const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]); |
| 1976 | C | // +3 For a blank on front and rounded edge each side: | | 2040 | C | // +3 For a blank on front and rounded edge each side: |
| | | 2041 | C | ctrlCharWidth[ll->chars[charInLine]] = |
| 1977 | C | ll->positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3; | | 2042 | C | surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + 3; |
| | | 2043 | C | } |
| | | 2044 | C | ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]]; |
|
| 1979 | U | 2046 | U | char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; |
|
| 1980 | U | 2047 | U | surface->MeasureWidths(ctrlCharsFont, cc, 1, |
|
| 78 skipped lines |
|
|
|
| | | 2129 | C | if (wrapState == eWrapChar){ |
| | | 2130 | C | lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1) |
| | | 2131 | C | - posLineStart; |
| | | 2132 | C | p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; |
| | | 2133 | C | continue; |
| 2062 | C | if (ll->styles[p] != ll->styles[p - 1]) { | | 2134 | C | } else if (ll->styles[p] != ll->styles[p - 1]) { |
| 2063 | U | 2135 | U | lastGoodBreak = p; |
|
| 2064 | U | 2136 | U | } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { |
|
| 2065 | U | 2137 | U | lastGoodBreak = p; |
|
| 292 skipped lines |
|
|
|
| | | 2433 | A | } else if (rcSegment.left > rcLine.right) { |
| | | 2434 | A | break; |
|
| 2362 | U | 2436 | U | startseg = i + 1; |
|
|
| 156 skipped lines |
| 2520 | U | 2594 | U | rcUL.bottom = rcUL.top + 1; |
|
|