OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / DocumentAccessor.cxx
1 // Scintilla source code edit control\r
2 /** @file DocumentAccessor.cxx\r
3  ** Rapid easy access to contents of a Scintilla.\r
4  **/\r
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>\r
6 // The License.txt file describes the conditions under which this software may be distributed.\r
7 \r
8 #include <stdlib.h>\r
9 #include <string.h>\r
10 #include <ctype.h>\r
11 #include <stdio.h>\r
12 \r
13 #include "Platform.h"\r
14 \r
15 #include "PropSet.h"\r
16 #include "Accessor.h"\r
17 #include "DocumentAccessor.h"\r
18 #include "SplitVector.h"\r
19 #include "Partitioning.h"\r
20 #include "RunStyles.h"\r
21 #include "CellBuffer.h"\r
22 #include "Scintilla.h"\r
23 #include "CharClassify.h"\r
24 #include "Decoration.h"\r
25 #include "Document.h"\r
26 \r
27 #ifdef SCI_NAMESPACE\r
28 using namespace Scintilla;\r
29 #endif\r
30 \r
31 DocumentAccessor::~DocumentAccessor() {\r
32 }\r
33 \r
34 bool DocumentAccessor::InternalIsLeadByte(char ch) {\r
35         if (SC_CP_UTF8 == codePage)\r
36                 // For lexing, all characters >= 0x80 are treated the\r
37                 // same so none is considered a lead byte.\r
38                 return false;\r
39         else\r
40                 return Platform::IsDBCSLeadByte(codePage, ch);\r
41 }\r
42 \r
43 void DocumentAccessor::Fill(int position) {\r
44         if (lenDoc == -1)\r
45                 lenDoc = pdoc->Length();\r
46         startPos = position - slopSize;\r
47         if (startPos + bufferSize > lenDoc)\r
48                 startPos = lenDoc - bufferSize;\r
49         if (startPos < 0)\r
50                 startPos = 0;\r
51         endPos = startPos + bufferSize;\r
52         if (endPos > lenDoc)\r
53                 endPos = lenDoc;\r
54 \r
55         pdoc->GetCharRange(buf, startPos, endPos-startPos);\r
56         buf[endPos-startPos] = '\0';\r
57 }\r
58 \r
59 bool DocumentAccessor::Match(int pos, const char *s) {\r
60         for (int i=0; *s; i++) {\r
61                 if (*s != SafeGetCharAt(pos+i))\r
62                         return false;\r
63                 s++;\r
64         }\r
65         return true;\r
66 }\r
67 \r
68 char DocumentAccessor::StyleAt(int position) {\r
69         // Mask off all bits which aren't in the 'mask'.\r
70         return static_cast<char>(pdoc->StyleAt(position) & mask);\r
71 }\r
72 \r
73 int DocumentAccessor::GetLine(int position) {\r
74         return pdoc->LineFromPosition(position);\r
75 }\r
76 \r
77 int DocumentAccessor::LineStart(int line) {\r
78         return pdoc->LineStart(line);\r
79 }\r
80 \r
81 int DocumentAccessor::LevelAt(int line) {\r
82         return pdoc->GetLevel(line);\r
83 }\r
84 \r
85 int DocumentAccessor::Length() {\r
86         if (lenDoc == -1)\r
87                 lenDoc = pdoc->Length();\r
88         return lenDoc;\r
89 }\r
90 \r
91 int DocumentAccessor::GetLineState(int line) {\r
92         return pdoc->GetLineState(line);\r
93 }\r
94 \r
95 int DocumentAccessor::SetLineState(int line, int state) {\r
96         return pdoc->SetLineState(line, state);\r
97 }\r
98 \r
99 void DocumentAccessor::StartAt(unsigned int start, char chMask) {\r
100         // Store the mask specified for use with StyleAt.\r
101         mask = chMask;\r
102         pdoc->StartStyling(start, chMask);\r
103         startPosStyling = start;\r
104 }\r
105 \r
106 void DocumentAccessor::StartSegment(unsigned int pos) {\r
107         startSeg = pos;\r
108 }\r
109 \r
110 void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {\r
111         // Only perform styling if non empty range\r
112         if (pos != startSeg - 1) {\r
113                 PLATFORM_ASSERT(pos >= startSeg);\r
114                 if (pos < startSeg) {\r
115                         return;\r
116                 }\r
117 \r
118                 if (validLen + (pos - startSeg + 1) >= bufferSize)\r
119                         Flush();\r
120                 if (validLen + (pos - startSeg + 1) >= bufferSize) {\r
121                         // Too big for buffer so send directly\r
122                         pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));\r
123                 } else {\r
124                         if (chAttr != chWhile)\r
125                                 chFlags = 0;\r
126                         chAttr |= chFlags;\r
127                         for (unsigned int i = startSeg; i <= pos; i++) {\r
128                                 PLATFORM_ASSERT((startPosStyling + validLen) < Length());\r
129                                 styleBuf[validLen++] = static_cast<char>(chAttr);\r
130                         }\r
131                 }\r
132         }\r
133         startSeg = pos+1;\r
134 }\r
135 \r
136 void DocumentAccessor::SetLevel(int line, int level) {\r
137         pdoc->SetLevel(line, level);\r
138 }\r
139 \r
140 void DocumentAccessor::Flush() {\r
141         startPos = extremePosition;\r
142         lenDoc = -1;\r
143         if (validLen > 0) {\r
144                 pdoc->SetStyles(validLen, styleBuf);\r
145                 startPosStyling += validLen;\r
146                 validLen = 0;\r
147         }\r
148 }\r
149 \r
150 int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {\r
151         int end = Length();\r
152         int spaceFlags = 0;\r
153 \r
154         // Determines the indentation level of the current line and also checks for consistent\r
155         // indentation compared to the previous line.\r
156         // Indentation is judged consistent when the indentation whitespace of each line lines\r
157         // the same or the indentation of one line is a prefix of the other.\r
158 \r
159         int pos = LineStart(line);\r
160         char ch = (*this)[pos];\r
161         int indent = 0;\r
162         bool inPrevPrefix = line > 0;\r
163         int posPrev = inPrevPrefix ? LineStart(line-1) : 0;\r
164         while ((ch == ' ' || ch == '\t') && (pos < end)) {\r
165                 if (inPrevPrefix) {\r
166                         char chPrev = (*this)[posPrev++];\r
167                         if (chPrev == ' ' || chPrev == '\t') {\r
168                                 if (chPrev != ch)\r
169                                         spaceFlags |= wsInconsistent;\r
170                         } else {\r
171                                 inPrevPrefix = false;\r
172                         }\r
173                 }\r
174                 if (ch == ' ') {\r
175                         spaceFlags |= wsSpace;\r
176                         indent++;\r
177                 } else {        // Tab\r
178                         spaceFlags |= wsTab;\r
179                         if (spaceFlags & wsSpace)\r
180                                 spaceFlags |= wsSpaceTab;\r
181                         indent = (indent / 8 + 1) * 8;\r
182                 }\r
183                 ch = (*this)[++pos];\r
184         }\r
185 \r
186         *flags = spaceFlags;\r
187         indent += SC_FOLDLEVELBASE;\r
188         // if completely empty line or the start of a comment...\r
189         if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||\r
190                 (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )\r
191                 return indent | SC_FOLDLEVELWHITEFLAG;\r
192         else\r
193                 return indent;\r
194 }\r
195 \r
196 void DocumentAccessor::IndicatorFill(int start, int end, int indicator, int value) {\r
197         pdoc->decorations.SetCurrentIndicator(indicator);\r
198         pdoc->DecorationFillRange(start, value, end - start);\r
199 }\r