geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

PositionCache.cxx
Go to the documentation of this file.
1// Scintilla source code edit control
2/** @file PositionCache.cxx
3 ** Classes for caching layout information.
4 **/
5// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
6// The License.txt file describes the conditions under which this software may be distributed.
7
8#include <cstddef>
9#include <cstdlib>
10#include <cstring>
11#include <cmath>
12
13#include <stdexcept>
14#include <string>
15#include <vector>
16#include <map>
17#include <algorithm>
18#include <iterator>
19#include <memory>
20
21#include "Platform.h"
22
23#include "ILoader.h"
24#include "ILexer.h"
25#include "Scintilla.h"
26
27#include "CharacterCategory.h"
28#include "Position.h"
29#include "UniqueString.h"
30#include "SplitVector.h"
31#include "Partitioning.h"
32#include "RunStyles.h"
33#include "ContractionState.h"
34#include "CellBuffer.h"
35#include "KeyMap.h"
36#include "Indicator.h"
37#include "LineMarker.h"
38#include "Style.h"
39#include "ViewStyle.h"
40#include "CharClassify.h"
41#include "Decoration.h"
42#include "CaseFolder.h"
43#include "Document.h"
44#include "UniConversion.h"
45#include "Selection.h"
46#include "PositionCache.h"
47
48using namespace Scintilla;
49
50LineLayout::LineLayout(int maxLineLength_) :
51 lenLineStarts(0),
52 lineNumber(-1),
53 inCache(false),
54 maxLineLength(-1),
55 numCharsInLine(0),
56 numCharsBeforeEOL(0),
57 validity(ValidLevel::invalid),
58 xHighlightGuide(0),
59 highlightColumn(false),
60 containsCaret(false),
61 edgeColumn(0),
62 bracePreviousStyles{},
63 hotspot(0,0),
64 widthLine(wrapWidthInfinite),
65 lines(1),
66 wrapIndent(0) {
67 Resize(maxLineLength_);
68}
69
71 Free();
72}
73
74void LineLayout::Resize(int maxLineLength_) {
75 if (maxLineLength_ > maxLineLength) {
76 Free();
77 chars = Sci::make_unique<char[]>(maxLineLength_ + 1);
78 styles = Sci::make_unique<unsigned char []>(maxLineLength_ + 1);
79 // Extra position allocated as sometimes the Windows
80 // GetTextExtentExPoint API writes an extra element.
81 positions = Sci::make_unique<XYPOSITION []>(maxLineLength_ + 1 + 1);
82 maxLineLength = maxLineLength_;
83 }
84}
85
86void LineLayout::Free() noexcept {
87 chars.reset();
88 styles.reset();
89 positions.reset();
90 lineStarts.reset();
91}
92
93void LineLayout::Invalidate(ValidLevel validity_) noexcept {
94 if (validity > validity_)
95 validity = validity_;
96}
97
98int LineLayout::LineStart(int line) const noexcept {
99 if (line <= 0) {
100 return 0;
101 } else if ((line >= lines) || !lineStarts) {
102 return numCharsInLine;
103 } else {
104 return lineStarts[line];
105 }
106}
107
108int LineLayout::LineLastVisible(int line, Scope scope) const noexcept {
109 if (line < 0) {
110 return 0;
111 } else if ((line >= lines-1) || !lineStarts) {
112 return scope == Scope::visibleOnly ? numCharsBeforeEOL : numCharsInLine;
113 } else {
114 return lineStarts[line+1];
115 }
116}
117
118Range LineLayout::SubLineRange(int subLine, Scope scope) const noexcept {
119 return Range(LineStart(subLine), LineLastVisible(subLine, scope));
120}
121
122bool LineLayout::InLine(int offset, int line) const noexcept {
123 return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) ||
124 ((offset == numCharsInLine) && (line == (lines-1)));
125}
126
127void LineLayout::SetLineStart(int line, int start) {
128 if ((line >= lenLineStarts) && (line != 0)) {
129 const int newMaxLines = line + 20;
130 std::unique_ptr<int[]> newLineStarts = Sci::make_unique<int[]>(newMaxLines);
131 for (int i = 0; i < newMaxLines; i++) {
132 if (i < lenLineStarts)
133 newLineStarts[i] = lineStarts[i];
134 else
135 newLineStarts[i] = 0;
136 }
137 lineStarts = std::move(newLineStarts);
138 lenLineStarts = newMaxLines;
139 }
140 lineStarts[line] = start;
141}
142
144 char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
145 if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
146 const Sci::Position braceOffset = braces[0] - rangeLine.start;
147 if (braceOffset < numCharsInLine) {
148 bracePreviousStyles[0] = styles[braceOffset];
149 styles[braceOffset] = bracesMatchStyle;
150 }
151 }
152 if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
153 const Sci::Position braceOffset = braces[1] - rangeLine.start;
154 if (braceOffset < numCharsInLine) {
155 bracePreviousStyles[1] = styles[braceOffset];
156 styles[braceOffset] = bracesMatchStyle;
157 }
158 }
159 if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) ||
160 (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) {
161 xHighlightGuide = xHighlight;
162 }
163}
164
165void LineLayout::RestoreBracesHighlight(Range rangeLine, const Sci::Position braces[], bool ignoreStyle) {
166 if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
167 const Sci::Position braceOffset = braces[0] - rangeLine.start;
168 if (braceOffset < numCharsInLine) {
169 styles[braceOffset] = bracePreviousStyles[0];
170 }
171 }
172 if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
173 const Sci::Position braceOffset = braces[1] - rangeLine.start;
174 if (braceOffset < numCharsInLine) {
175 styles[braceOffset] = bracePreviousStyles[1];
176 }
177 }
178 xHighlightGuide = 0;
179}
180
181int LineLayout::FindBefore(XYPOSITION x, Range range) const noexcept {
182 Sci::Position lower = range.start;
183 Sci::Position upper = range.end;
184 do {
185 const Sci::Position middle = (upper + lower + 1) / 2; // Round high
186 const XYPOSITION posMiddle = positions[middle];
187 if (x < posMiddle) {
188 upper = middle - 1;
189 } else {
190 lower = middle;
191 }
192 } while (lower < upper);
193 return static_cast<int>(lower);
194}
195
196
197int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept {
198 int pos = FindBefore(x, range);
199 while (pos < range.end) {
200 if (charPosition) {
201 if (x < (positions[pos + 1])) {
202 return pos;
203 }
204 } else {
205 if (x < ((positions[pos] + positions[pos + 1]) / 2)) {
206 return pos;
207 }
208 }
209 pos++;
210 }
211 return static_cast<int>(range.end);
212}
213
214Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept {
215 Point pt;
216 // In case of very long line put x at arbitrary large position
217 if (posInLine > maxLineLength) {
218 pt.x = positions[maxLineLength] - positions[LineStart(lines)];
219 }
220
221 for (int subLine = 0; subLine < lines; subLine++) {
222 const Range rangeSubLine = SubLineRange(subLine, Scope::visibleOnly);
223 if (posInLine >= rangeSubLine.start) {
224 pt.y = static_cast<XYPOSITION>(subLine*lineHeight);
225 if (posInLine <= rangeSubLine.end) {
226 pt.x = positions[posInLine] - positions[rangeSubLine.start];
227 if (rangeSubLine.start != 0) // Wrapped lines may be indented
228 pt.x += wrapIndent;
229 if (pe & peSubLineEnd) // Return end of first subline not start of next
230 break;
231 } else if ((pe & peLineEnd) && (subLine == (lines-1))) {
232 pt.x = positions[numCharsInLine] - positions[rangeSubLine.start];
233 if (rangeSubLine.start != 0) // Wrapped lines may be indented
234 pt.x += wrapIndent;
235 }
236 } else {
237 break;
238 }
239 }
240 return pt;
241}
242
243int LineLayout::EndLineStyle() const noexcept {
244 return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
245}
246
248 level(0),
249 allInvalidated(false), styleClock(-1), useCount(0) {
250 Allocate(0);
251}
252
254 Deallocate();
255}
256
257void LineLayoutCache::Allocate(size_t length_) {
258 PLATFORM_ASSERT(cache.empty());
259 allInvalidated = false;
260 cache.resize(length_);
261}
262
265 size_t lengthForLevel = 0;
266 if (level == llcCaret) {
267 lengthForLevel = 1;
268 } else if (level == llcPage) {
269 lengthForLevel = linesOnScreen + 1;
270 } else if (level == llcDocument) {
271 lengthForLevel = linesInDoc;
272 }
273 if (lengthForLevel > cache.size()) {
274 Deallocate();
275 Allocate(lengthForLevel);
276 } else {
277 if (lengthForLevel < cache.size()) {
278 for (size_t i = lengthForLevel; i < cache.size(); i++) {
279 cache[i].reset();
280 }
281 }
282 cache.resize(lengthForLevel);
283 }
284 PLATFORM_ASSERT(cache.size() == lengthForLevel);
285}
286
289 cache.clear();
290}
291
293 if (!cache.empty() && !allInvalidated) {
294 for (const std::unique_ptr<LineLayout> &ll : cache) {
295 if (ll) {
296 ll->Invalidate(validity_);
297 }
298 }
299 if (validity_ == LineLayout::ValidLevel::invalid) {
300 allInvalidated = true;
301 }
302 }
303}
304
305void LineLayoutCache::SetLevel(int level_) noexcept {
306 allInvalidated = false;
307 if ((level_ != -1) && (level != level_)) {
308 level = level_;
309 Deallocate();
310 }
311}
312
313LineLayout *LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_,
314 Sci::Line linesOnScreen, Sci::Line linesInDoc) {
315 AllocateForLevel(linesOnScreen, linesInDoc);
316 if (styleClock != styleClock_) {
318 styleClock = styleClock_;
319 }
320 allInvalidated = false;
321 Sci::Position pos = -1;
322 LineLayout *ret = nullptr;
323 if (level == llcCaret) {
324 pos = 0;
325 } else if (level == llcPage) {
326 if (lineNumber == lineCaret) {
327 pos = 0;
328 } else if (cache.size() > 1) {
329 pos = 1 + (lineNumber % (cache.size() - 1));
330 }
331 } else if (level == llcDocument) {
332 pos = lineNumber;
333 }
334 if (pos >= 0) {
336 if (!cache.empty() && (pos < static_cast<int>(cache.size()))) {
337 if (cache[pos]) {
338 if ((cache[pos]->lineNumber != lineNumber) ||
339 (cache[pos]->maxLineLength < maxChars)) {
340 cache[pos].reset();
341 }
342 }
343 if (!cache[pos]) {
344 cache[pos] = Sci::make_unique<LineLayout>(maxChars);
345 }
346 cache[pos]->lineNumber = lineNumber;
347 cache[pos]->inCache = true;
348 ret = cache[pos].get();
349 useCount++;
350 }
351 }
352
353 if (!ret) {
354 ret = new LineLayout(maxChars);
355 ret->lineNumber = lineNumber;
356 }
357
358 return ret;
359}
360
362 allInvalidated = false;
363 if (ll) {
364 if (!ll->inCache) {
365 delete ll;
366 } else {
367 useCount--;
368 }
369 }
370}
371
372// Simply pack the (maximum 4) character bytes into an int
373static unsigned int KeyFromString(const char *charBytes, size_t len) noexcept {
374 PLATFORM_ASSERT(len <= 4);
375 unsigned int k=0;
376 for (size_t i=0; i<len && charBytes[i]; i++) {
377 k = k * 0x100;
378 const unsigned char uc = charBytes[i];
379 k += uc;
380 }
381 return k;
382}
383
385 const short none = 0;
387}
388
389void SpecialRepresentations::SetRepresentation(const char *charBytes, const char *value) {
390 const unsigned int key = KeyFromString(charBytes, UTF8MaxBytes);
391 MapRepresentation::iterator it = mapReprs.find(key);
392 if (it == mapReprs.end()) {
393 // New entry so increment for first byte
394 const unsigned char ucStart = charBytes[0];
395 startByteHasReprs[ucStart]++;
396 }
397 mapReprs[key] = Representation(value);
398}
399
401 MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, UTF8MaxBytes));
402 if (it != mapReprs.end()) {
403 mapReprs.erase(it);
404 const unsigned char ucStart = charBytes[0];
405 startByteHasReprs[ucStart]--;
406 }
407}
408
409const Representation *SpecialRepresentations::RepresentationFromCharacter(const char *charBytes, size_t len) const {
410 PLATFORM_ASSERT(len <= 4);
411 const unsigned char ucStart = charBytes[0];
412 if (!startByteHasReprs[ucStart])
413 return nullptr;
414 MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len));
415 if (it != mapReprs.end()) {
416 return &(it->second);
417 }
418 return nullptr;
419}
420
421bool SpecialRepresentations::Contains(const char *charBytes, size_t len) const {
422 PLATFORM_ASSERT(len <= 4);
423 const unsigned char ucStart = charBytes[0];
424 if (!startByteHasReprs[ucStart])
425 return false;
426 MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len));
427 return it != mapReprs.end();
428}
429
431 mapReprs.clear();
432 const short none = 0;
434}
435
437 const int posInLine = static_cast<int>(val);
438 if (posInLine > nextBreak) {
439 const std::vector<int>::iterator it = std::lower_bound(selAndEdge.begin(), selAndEdge.end(), posInLine);
440 if (it == selAndEdge.end()) {
441 selAndEdge.push_back(posInLine);
442 } else if (*it != posInLine) {
443 selAndEdge.insert(it, 1, posInLine);
444 }
445 }
446}
447
448BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_,
449 int xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw) :
450 ll(ll_),
451 lineRange(lineRange_),
452 posLineStart(posLineStart_),
453 nextBreak(static_cast<int>(lineRange_.start)),
454 saeCurrentPos(0),
455 saeNext(0),
456 subBreak(-1),
457 pdoc(pdoc_),
458 encodingFamily(pdoc_->CodePageFamily()),
459 preprs(preprs_) {
460
461 // Search for first visible break
462 // First find the first visible character
463 if (xStart > 0.0f)
464 nextBreak = ll->FindBefore(static_cast<XYPOSITION>(xStart), lineRange);
465 // Now back to a style break
466 while ((nextBreak > lineRange.start) && (ll->styles[nextBreak] == ll->styles[nextBreak - 1])) {
467 nextBreak--;
468 }
469
470 if (breakForSelection) {
471 const SelectionPosition posStart(posLineStart);
473 const SelectionSegment segmentLine(posStart, posEnd);
474 for (size_t r=0; r<psel->Count(); r++) {
475 const SelectionSegment portion = psel->Range(r).Intersect(segmentLine);
476 if (!(portion.start == portion.end)) {
477 if (portion.start.IsValid())
478 Insert(portion.start.Position() - posLineStart);
479 if (portion.end.IsValid())
480 Insert(portion.end.Position() - posLineStart);
481 }
482 }
483 }
484 if (pvsDraw && pvsDraw->indicatorsSetFore) {
485 for (const IDecoration *deco : pdoc->decorations->View()) {
486 if (pvsDraw->indicators[deco->Indicator()].OverridesTextFore()) {
487 Sci::Position startPos = deco->EndRun(posLineStart);
488 while (startPos < (posLineStart + lineRange.end)) {
489 Insert(startPos - posLineStart);
490 startPos = deco->EndRun(startPos);
491 }
492 }
493 }
494 }
497 saeNext = (!selAndEdge.empty()) ? selAndEdge[0] : -1;
498}
499
501}
502
504 if (subBreak == -1) {
505 const int prev = nextBreak;
506 while (nextBreak < lineRange.end) {
507 int charWidth = 1;
509 charWidth = UTF8DrawBytes(reinterpret_cast<unsigned char *>(&ll->chars[nextBreak]),
510 static_cast<int>(lineRange.end - nextBreak));
512 charWidth = pdoc->DBCSDrawBytes(
513 &ll->chars[nextBreak], static_cast<int>(lineRange.end - nextBreak));
515 if (((nextBreak > 0) && (ll->styles[nextBreak] != ll->styles[nextBreak - 1])) ||
516 repr ||
517 (nextBreak == saeNext)) {
518 while ((nextBreak >= saeNext) && (saeNext < lineRange.end)) {
520 saeNext = static_cast<int>((saeCurrentPos < selAndEdge.size()) ? selAndEdge[saeCurrentPos] : lineRange.end);
521 }
522 if ((nextBreak > prev) || repr) {
523 // Have a segment to report
524 if (nextBreak == prev) {
525 nextBreak += charWidth;
526 } else {
527 repr = nullptr; // Optimize -> should remember repr
528 }
529 if ((nextBreak - prev) < lengthStartSubdivision) {
530 return TextSegment(prev, nextBreak - prev, repr);
531 } else {
532 break;
533 }
534 }
535 }
536 nextBreak += charWidth;
537 }
538 if ((nextBreak - prev) < lengthStartSubdivision) {
539 return TextSegment(prev, nextBreak - prev);
540 }
541 subBreak = prev;
542 }
543 // Splitting up a long run from prev to nextBreak in lots of approximately lengthEachSubdivision.
544 // For very long runs add extra breaks after spaces or if no spaces before low punctuation.
545 const int startSegment = subBreak;
547 subBreak = -1;
548 return TextSegment(startSegment, nextBreak - startSegment);
549 } else {
551 if (subBreak >= nextBreak) {
552 subBreak = -1;
553 return TextSegment(startSegment, nextBreak - startSegment);
554 } else {
555 return TextSegment(startSegment, subBreak - startSegment);
556 }
557 }
558}
559
560bool BreakFinder::More() const noexcept {
561 return (subBreak >= 0) || (nextBreak < lineRange.end);
562}
563
565 styleNumber(0), len(0), clock(0), positions(nullptr) {
566}
567
568// Copy constructor not currently used, but needed for being element in std::vector.
570 styleNumber(other.styleNumber), len(other.styleNumber), clock(other.styleNumber), positions(nullptr) {
571 if (other.positions) {
572 const size_t lenData = len + (len / sizeof(XYPOSITION)) + 1;
573 positions = Sci::make_unique<XYPOSITION[]>(lenData);
574 memcpy(positions.get(), other.positions.get(), lenData * sizeof(XYPOSITION));
575 }
576}
577
578void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_,
579 unsigned int len_, const XYPOSITION *positions_, unsigned int clock_) {
580 Clear();
581 styleNumber = styleNumber_;
582 len = len_;
583 clock = clock_;
584 if (s_ && positions_) {
585 positions = Sci::make_unique<XYPOSITION[]>(len + (len / sizeof(XYPOSITION)) + 1);
586 for (unsigned int i=0; i<len; i++) {
587 positions[i] = positions_[i];
588 }
589 memcpy(&positions[len], s_, len);
590 }
591}
592
594 Clear();
595}
596
598 positions.reset();
599 styleNumber = 0;
600 len = 0;
601 clock = 0;
602}
603
604bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
605 unsigned int len_, XYPOSITION *positions_) const noexcept {
606 if ((styleNumber == styleNumber_) && (len == len_) &&
607 (memcmp(&positions[len], s_, len)== 0)) {
608 for (unsigned int i=0; i<len; i++) {
609 positions_[i] = positions[i];
610 }
611 return true;
612 } else {
613 return false;
614 }
615}
616
617unsigned int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) noexcept {
618 unsigned int ret = s[0] << 7;
619 for (unsigned int i=0; i<len_; i++) {
620 ret *= 1000003;
621 ret ^= s[i];
622 }
623 ret *= 1000003;
624 ret ^= len_;
625 ret *= 1000003;
626 ret ^= styleNumber_;
627 return ret;
628}
629
630bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const noexcept {
631 return clock > other.clock;
632}
633
635 if (clock > 0) {
636 clock = 1;
637 }
638}
639
641 clock = 1;
642 pces.resize(0x400);
643 allClear = true;
644}
645
647 Clear();
648}
649
650void PositionCache::Clear() noexcept {
651 if (!allClear) {
652 for (PositionCacheEntry &pce : pces) {
653 pce.Clear();
654 }
655 }
656 clock = 1;
657 allClear = true;
658}
659
660void PositionCache::SetSize(size_t size_) {
661 Clear();
662 pces.resize(size_);
663}
664
665void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
666 const char *s, unsigned int len, XYPOSITION *positions, const Document *pdoc) {
667
668 allClear = false;
669 size_t probe = pces.size(); // Out of bounds
670 if ((!pces.empty()) && (len < 30)) {
671 // Only store short strings in the cache so it doesn't churn with
672 // long comments with only a single comment.
673
674 // Two way associative: try two probe positions.
675 const unsigned int hashValue = PositionCacheEntry::Hash(styleNumber, s, len);
676 probe = hashValue % pces.size();
677 if (pces[probe].Retrieve(styleNumber, s, len, positions)) {
678 return;
679 }
680 const unsigned int probe2 = (hashValue * 37) % pces.size();
681 if (pces[probe2].Retrieve(styleNumber, s, len, positions)) {
682 return;
683 }
684 // Not found. Choose the oldest of the two slots to replace
685 if (pces[probe].NewerThan(pces[probe2])) {
686 probe = probe2;
687 }
688 }
689 FontAlias fontStyle = vstyle.styles[styleNumber].font;
691 // Break up into segments
692 unsigned int startSegment = 0;
693 XYPOSITION xStartSegment = 0;
694 while (startSegment < len) {
695 const unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
696 surface->MeasureWidths(fontStyle, s + startSegment, lenSegment, positions + startSegment);
697 for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
698 positions[startSegment + inSeg] += xStartSegment;
699 }
700 xStartSegment = positions[startSegment + lenSegment - 1];
701 startSegment += lenSegment;
702 }
703 } else {
704 surface->MeasureWidths(fontStyle, s, len, positions);
705 }
706 if (probe < pces.size()) {
707 // Store into cache
708 clock++;
709 if (clock > 60000) {
710 // Since there are only 16 bits for the clock, wrap it round and
711 // reset all cache entries so none get stuck with a high clock.
712 for (PositionCacheEntry &pce : pces) {
713 pce.ResetClock();
714 }
715 clock = 2;
716 }
717 pces[probe].Set(styleNumber, s, len, positions, clock);
718 }
719}
Classes for case folding.
Manages the text of the document.
Character classifications used by Document and RESearch.
Returns the Unicode general category of a character.
Manages visibility of lines for folding and wrapping.
Visual elements added over text.
Text document that handles notifications, DBCS, styling, words and end of line.
Interface between Scintilla and lexers.
Interface for loading into a Scintilla document from a background thread.
Defines the style of indicators which are text decorations such as underlining.
Defines a mapping between keystrokes and commands.
static Sci_Position LineStart(Sci_Position line, Accessor &styler)
Definition: LexAbaqus.cxx:315
Defines the look of a line marker in the margin .
Data structure used to partition an interval.
Interface to platform facilities.
#define PLATFORM_ASSERT(c)
Definition: Platform.h:544
static unsigned int KeyFromString(const char *charBytes, size_t len) noexcept
Classes for caching layout information.
Defines global type name Position in the Sci internal namespace.
Data structure used to store sparse styles.
Interface to the edit control.
Classes maintaining the selection.
Main data structure for holding arrays that handle insertions and deletions efficiently.
Defines the font and colour style for a class of text.
Functions to handle UTF-8 and UTF-16 strings.
Define UniqueString, a unique_ptr based string type for storage in containers and an allocator for Un...
Store information on how the document is to be viewed.
const LineLayout * ll
void Insert(Sci::Position val)
BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_, int xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw)
bool More() const noexcept
Sci::Position posLineStart
EncodingFamily encodingFamily
unsigned int saeCurrentPos
const Document * pdoc
std::vector< int > selAndEdge
const SpecialRepresentations * preprs
std::unique_ptr< IDecorationList > decorations
Definition: Document.h:286
int SafeSegment(const char *text, int length, int lengthSegment) const noexcept
Definition: Document.cxx:1145
int DBCSDrawBytes(const char *text, int len) const noexcept
Definition: Document.cxx:1119
void Dispose(LineLayout *ll) noexcept
LineLayout * Retrieve(Sci::Line lineNumber, Sci::Line lineCaret, int maxChars, int styleClock_, Sci::Line linesOnScreen, Sci::Line linesInDoc)
std::vector< std::unique_ptr< LineLayout > > cache
void AllocateForLevel(Sci::Line linesOnScreen, Sci::Line linesInDoc)
void Invalidate(LineLayout::ValidLevel validity_) noexcept
void Allocate(size_t length_)
void SetLevel(int level_) noexcept
int LineLastVisible(int line, Scope scope) const noexcept
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept
std::unique_ptr< int[]> lineStarts
Definition: PositionCache.h:52
int FindBefore(XYPOSITION x, Range range) const noexcept
int LineStart(int line) const noexcept
void Resize(int maxLineLength_)
Range SubLineRange(int subLine, Scope scope) const noexcept
std::unique_ptr< char[]> chars
Definition: PositionCache.h:68
void SetBracesHighlight(Range rangeLine, const Sci::Position braces[], char bracesMatchStyle, int xHighlight, bool ignoreStyle)
std::unique_ptr< XYPOSITION[]> positions
Definition: PositionCache.h:70
int EndLineStyle() const noexcept
std::unique_ptr< unsigned char[]> styles
Definition: PositionCache.h:69
Sci::Line lineNumber
Drawing is only performed for maxLineLength characters on each line.
Definition: PositionCache.h:55
bool InLine(int offset, int line) const noexcept
void SetLineStart(int line, int start)
void Invalidate(ValidLevel validity_) noexcept
Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept
void RestoreBracesHighlight(Range rangeLine, const Sci::Position braces[], bool ignoreStyle)
void Free() noexcept
A geometric point class.
Definition: Platform.h:99
XYPOSITION y
Definition: Platform.h:102
XYPOSITION x
Definition: Platform.h:101
static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len_) noexcept
std::unique_ptr< XYPOSITION[]> positions
bool NewerThan(const PositionCacheEntry &other) const noexcept
void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, const XYPOSITION *positions_, unsigned int clock_)
bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const noexcept
void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, const char *s, unsigned int len, XYPOSITION *positions, const Document *pdoc)
std::vector< PositionCacheEntry > pces
void SetSize(size_t size_)
The range class represents a range of text in a document.
Definition: Document.h:29
Sci::Position end
Definition: Document.h:32
Sci::Position start
Definition: Document.h:31
bool ContainsCharacter(Sci::Position pos) const noexcept
Definition: Document.h:67
Sci::Position Position() const noexcept
Definition: Selection.h:34
bool IsValid() const noexcept
Definition: Selection.h:52
size_t Count() const noexcept
Definition: Selection.cxx:237
SelectionRange & Range(size_t r) noexcept
Definition: Selection.cxx:250
const Representation * RepresentationFromCharacter(const char *charBytes, size_t len) const
bool Contains(const char *charBytes, size_t len) const
void ClearRepresentation(const char *charBytes)
void SetRepresentation(const char *charBytes, const char *value)
A surface abstracts a place to draw.
Definition: Platform.h:340
virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0
std::vector< Style > styles
Definition: ViewStyle.h:84
std::vector< Indicator > indicators
Definition: ViewStyle.h:88
gint pos
Definition: editor.c:87
#define fill(Order, Group, Idx, Charset, Name)
Definition: encodings.c:62
unsigned long int lineNumber
Definition: geany_cobol.c:134
vString * line
Definition: geany_cobol.c:133
static vString * scope
Definition: geany_go.c:78
static unsigned int hashValue(const char *const string, langType language)
Definition: keyword.c:73
ptrdiff_t Position
Definition: Position.h:19
ptrdiff_t Line
Definition: Position.h:20
Styling buffer using one element for each run rather than using a filled buffer.
Definition: Converter.h:9
constexpr int UTF8MaxBytes
Definition: UniConversion.h:13
float XYPOSITION
Definition: Platform.h:81
int UTF8DrawBytes(const unsigned char *us, int len) noexcept
long lines
Definition: stats.c:32
SelectionSegment Intersect(SelectionSegment check) const noexcept
Definition: Selection.cxx:126
SelectionPosition end
Definition: Selection.h:60
SelectionPosition start
Definition: Selection.h:59