1 // SciTE - Scintilla based Text Editor
2 /** @file StyleWriter.cxx
3 ** Simple buffered interface to the text and styles of a document held by Scintilla.
4 **/
5 // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #include <cstdint>
9
10 #include <string>
11 #include <string_view>
12 #include <chrono>
13
14 #include "ScintillaTypes.h"
15 #include "ScintillaCall.h"
16
17 #include "GUI.h"
18 #include "StyleWriter.h"
19
20 namespace SA = Scintilla::API;
21
TextReader(SA::ScintillaCall & sc_)22 TextReader::TextReader(SA::ScintillaCall &sc_) noexcept :
23 startPos(extremePosition),
24 endPos(0),
25 codePage(0),
26 sc(sc_),
27 lenDoc(-1) {
28 buf[0] = 0;
29 }
30
InternalIsLeadByte(char ch) const31 bool TextReader::InternalIsLeadByte(char ch) const {
32 return GUI::IsDBCSLeadByte(codePage, ch);
33 }
34
Fill(SA::Position position)35 void TextReader::Fill(SA::Position position) {
36 if (lenDoc == -1)
37 lenDoc = sc.Length();
38 startPos = position - slopSize;
39 if (startPos + bufferSize > lenDoc)
40 startPos = lenDoc - bufferSize;
41 if (startPos < 0)
42 startPos = 0;
43 endPos = startPos + bufferSize;
44 if (endPos > lenDoc)
45 endPos = lenDoc;
46 sc.SetTarget(SA::Range(startPos, endPos));
47 sc.TargetText(buf);
48 }
49
Match(SA::Position pos,const char * s)50 bool TextReader::Match(SA::Position pos, const char *s) {
51 for (int i=0; *s; i++) {
52 if (*s != SafeGetCharAt(pos+i))
53 return false;
54 s++;
55 }
56 return true;
57 }
58
StyleAt(SA::Position position)59 int TextReader::StyleAt(SA::Position position) {
60 return sc.UnsignedStyleAt(position);
61 }
62
GetLine(SA::Position position)63 SA::Line TextReader::GetLine(SA::Position position) {
64 return sc.LineFromPosition(position);
65 }
66
LineStart(SA::Line line)67 SA::Position TextReader::LineStart(SA::Line line) {
68 return sc.LineStart(line);
69 }
70
LevelAt(SA::Line line)71 SA::FoldLevel TextReader::LevelAt(SA::Line line) {
72 return sc.FoldLevel(line);
73 }
74
Length()75 SA::Position TextReader::Length() {
76 if (lenDoc == -1)
77 lenDoc = sc.Length();
78 return lenDoc;
79 }
80
GetLineState(SA::Line line)81 int TextReader::GetLineState(SA::Line line) {
82 return sc.LineState(line);
83 }
84
StyleWriter(SA::ScintillaCall & sc_)85 StyleWriter::StyleWriter(SA::ScintillaCall &sc_) noexcept :
86 TextReader(sc_),
87 validLen(0),
88 startSeg(0) {
89 styleBuf[0] = 0;
90 }
91
SetLineState(SA::Line line,int state)92 void StyleWriter::SetLineState(SA::Line line, int state) {
93 sc.SetLineState(line, state);
94 }
95
StartAt(SA::Position start,char chMask)96 void StyleWriter::StartAt(SA::Position start, char chMask) {
97 sc.StartStyling(start, chMask);
98 }
99
StartSegment(SA::Position pos)100 void StyleWriter::StartSegment(SA::Position pos) noexcept {
101 startSeg = pos;
102 }
103
ColourTo(SA::Position pos,int chAttr)104 void StyleWriter::ColourTo(SA::Position pos, int chAttr) {
105 // Only perform styling if non empty range
106 if (pos != startSeg - 1) {
107 if (validLen + (pos - startSeg + 1) >= bufferSize)
108 Flush();
109 if (validLen + (pos - startSeg + 1) >= bufferSize) {
110 // Too big for buffer so send directly
111 sc.SetStyling(pos - startSeg + 1, chAttr);
112 } else {
113 for (SA::Position i = startSeg; i <= pos; i++) {
114 styleBuf[validLen++] = static_cast<char>(chAttr);
115 }
116 }
117 }
118 startSeg = pos+1;
119 }
120
SetLevel(SA::Line line,SA::FoldLevel level)121 void StyleWriter::SetLevel(SA::Line line, SA::FoldLevel level) {
122 sc.SetFoldLevel(line, level);
123 }
124
Flush()125 void StyleWriter::Flush() {
126 startPos = extremePosition;
127 lenDoc = -1;
128 if (validLen > 0) {
129 sc.SetStylingEx(validLen, styleBuf);
130 validLen = 0;
131 }
132 }
133