]>
Commit | Line | Data |
---|---|---|
9ce192d4 | 1 | // Scintilla source code edit control |
65ec6247 RD |
2 | /** @file ViewStyle.cxx |
3 | ** Store information on how the document is to be viewed. | |
4 | **/ | |
9e730a78 | 5 | // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> |
9ce192d4 RD |
6 | // The License.txt file describes the conditions under which this software may be distributed. |
7 | ||
8 | #include <string.h> | |
9 | ||
10 | #include "Platform.h" | |
11 | ||
12 | #include "Scintilla.h" | |
7e0c58e9 RD |
13 | #include "SplitVector.h" |
14 | #include "Partitioning.h" | |
15 | #include "RunStyles.h" | |
9ce192d4 | 16 | #include "Indicator.h" |
9e730a78 | 17 | #include "XPM.h" |
9ce192d4 RD |
18 | #include "LineMarker.h" |
19 | #include "Style.h" | |
20 | #include "ViewStyle.h" | |
21 | ||
7e0c58e9 RD |
22 | #ifdef SCI_NAMESPACE |
23 | using namespace Scintilla; | |
24 | #endif | |
25 | ||
65ec6247 | 26 | MarginStyle::MarginStyle() : |
b8193d80 | 27 | style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false) { |
9ce192d4 RD |
28 | } |
29 | ||
f6bcfd97 BP |
30 | // A list of the fontnames - avoids wasting space in each style |
31 | FontNames::FontNames() { | |
7e0c58e9 RD |
32 | size = 8; |
33 | names = new char *[size]; | |
f6bcfd97 BP |
34 | max = 0; |
35 | } | |
36 | ||
37 | FontNames::~FontNames() { | |
38 | Clear(); | |
7e0c58e9 RD |
39 | delete []names; |
40 | names = 0; | |
f6bcfd97 BP |
41 | } |
42 | ||
43 | void FontNames::Clear() { | |
44 | for (int i=0;i<max;i++) { | |
45 | delete []names[i]; | |
46 | } | |
47 | max = 0; | |
48 | } | |
49 | ||
50 | const char *FontNames::Save(const char *name) { | |
51 | if (!name) | |
52 | return 0; | |
53 | for (int i=0;i<max;i++) { | |
54 | if (strcmp(names[i], name) == 0) { | |
55 | return names[i]; | |
56 | } | |
57 | } | |
7e0c58e9 RD |
58 | if (max >= size) { |
59 | // Grow array | |
60 | int sizeNew = size * 2; | |
61 | char **namesNew = new char *[sizeNew]; | |
62 | for (int j=0;j<max;j++) { | |
63 | namesNew[j] = names[j]; | |
64 | } | |
65 | delete []names; | |
66 | names = namesNew; | |
67 | size = sizeNew; | |
68 | } | |
f6bcfd97 BP |
69 | names[max] = new char[strlen(name) + 1]; |
70 | strcpy(names[max], name); | |
71 | max++; | |
72 | return names[max-1]; | |
73 | } | |
74 | ||
9ce192d4 RD |
75 | ViewStyle::ViewStyle() { |
76 | Init(); | |
77 | } | |
78 | ||
79 | ViewStyle::ViewStyle(const ViewStyle &source) { | |
7e0c58e9 RD |
80 | Init(source.stylesSize); |
81 | for (unsigned int sty=0;sty<source.stylesSize;sty++) { | |
9ce192d4 | 82 | styles[sty] = source.styles[sty]; |
f6bcfd97 BP |
83 | // Can't just copy fontname as its lifetime is relative to its owning ViewStyle |
84 | styles[sty].fontName = fontNames.Save(source.styles[sty].fontName); | |
9ce192d4 RD |
85 | } |
86 | for (int mrk=0;mrk<=MARKER_MAX;mrk++) { | |
87 | markers[mrk] = source.markers[mrk]; | |
88 | } | |
89 | for (int ind=0;ind<=INDIC_MAX;ind++) { | |
90 | indicators[ind] = source.indicators[ind]; | |
91 | } | |
65ec6247 | 92 | |
9ce192d4 RD |
93 | selforeset = source.selforeset; |
94 | selforeground.desired = source.selforeground.desired; | |
95 | selbackset = source.selbackset; | |
96 | selbackground.desired = source.selbackground.desired; | |
d134f170 | 97 | selbackground2.desired = source.selbackground2.desired; |
b8193d80 | 98 | selAlpha = source.selAlpha; |
7e0c58e9 | 99 | selEOLFilled = source.selEOLFilled; |
9e730a78 RD |
100 | |
101 | foldmarginColourSet = source.foldmarginColourSet; | |
102 | foldmarginColour.desired = source.foldmarginColour.desired; | |
103 | foldmarginHighlightColourSet = source.foldmarginHighlightColourSet; | |
104 | foldmarginHighlightColour.desired = source.foldmarginHighlightColour.desired; | |
105 | ||
106 | hotspotForegroundSet = source.hotspotForegroundSet; | |
107 | hotspotForeground.desired = source.hotspotForeground.desired; | |
108 | hotspotBackgroundSet = source.hotspotBackgroundSet; | |
109 | hotspotBackground.desired = source.hotspotBackground.desired; | |
110 | hotspotUnderline = source.hotspotUnderline; | |
8e54aaed | 111 | hotspotSingleLine = source.hotspotSingleLine; |
9e730a78 | 112 | |
f114b858 RD |
113 | whitespaceForegroundSet = source.whitespaceForegroundSet; |
114 | whitespaceForeground.desired = source.whitespaceForeground.desired; | |
115 | whitespaceBackgroundSet = source.whitespaceBackgroundSet; | |
116 | whitespaceBackground.desired = source.whitespaceBackground.desired; | |
9ce192d4 RD |
117 | selbar.desired = source.selbar.desired; |
118 | selbarlight.desired = source.selbarlight.desired; | |
119 | caretcolour.desired = source.caretcolour.desired; | |
65ec6247 RD |
120 | showCaretLineBackground = source.showCaretLineBackground; |
121 | caretLineBackground.desired = source.caretLineBackground.desired; | |
b8193d80 | 122 | caretLineAlpha = source.caretLineAlpha; |
9ce192d4 | 123 | edgecolour.desired = source.edgecolour.desired; |
d134f170 | 124 | edgeState = source.edgeState; |
7e0c58e9 | 125 | caretStyle = source.caretStyle; |
65ec6247 | 126 | caretWidth = source.caretWidth; |
591d01be | 127 | someStylesProtected = false; |
9ce192d4 RD |
128 | leftMarginWidth = source.leftMarginWidth; |
129 | rightMarginWidth = source.rightMarginWidth; | |
130 | for (int i=0;i < margins; i++) { | |
131 | ms[i] = source.ms[i]; | |
132 | } | |
133 | symbolMargin = source.symbolMargin; | |
134 | maskInLine = source.maskInLine; | |
135 | fixedColumnWidth = source.fixedColumnWidth; | |
136 | zoomLevel = source.zoomLevel; | |
137 | viewWhitespace = source.viewWhitespace; | |
d134f170 | 138 | viewIndentationGuides = source.viewIndentationGuides; |
9ce192d4 | 139 | viewEOL = source.viewEOL; |
65ec6247 | 140 | showMarkedLines = source.showMarkedLines; |
591d01be | 141 | extraFontFlag = source.extraFontFlag; |
9ce192d4 RD |
142 | } |
143 | ||
144 | ViewStyle::~ViewStyle() { | |
7e0c58e9 RD |
145 | delete []styles; |
146 | styles = NULL; | |
9ce192d4 RD |
147 | } |
148 | ||
7e0c58e9 RD |
149 | void ViewStyle::Init(size_t stylesSize_) { |
150 | stylesSize = 0; | |
151 | styles = NULL; | |
152 | AllocStyles(stylesSize_); | |
f6bcfd97 BP |
153 | fontNames.Clear(); |
154 | ResetDefaultStyle(); | |
65ec6247 | 155 | |
9ce192d4 | 156 | indicators[0].style = INDIC_SQUIGGLE; |
7e0c58e9 | 157 | indicators[0].under = false; |
1a2fb4cd | 158 | indicators[0].fore = ColourDesired(0, 0x7f, 0); |
9ce192d4 | 159 | indicators[1].style = INDIC_TT; |
7e0c58e9 | 160 | indicators[1].under = false; |
1a2fb4cd | 161 | indicators[1].fore = ColourDesired(0, 0, 0xff); |
9ce192d4 | 162 | indicators[2].style = INDIC_PLAIN; |
7e0c58e9 | 163 | indicators[2].under = false; |
1a2fb4cd | 164 | indicators[2].fore = ColourDesired(0xff, 0, 0); |
9ce192d4 RD |
165 | |
166 | lineHeight = 1; | |
167 | maxAscent = 1; | |
168 | maxDescent = 1; | |
169 | aveCharWidth = 8; | |
170 | spaceWidth = 8; | |
171 | ||
172 | selforeset = false; | |
1a2fb4cd | 173 | selforeground.desired = ColourDesired(0xff, 0, 0); |
9ce192d4 | 174 | selbackset = true; |
1a2fb4cd RD |
175 | selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0); |
176 | selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0); | |
b8193d80 | 177 | selAlpha = SC_ALPHA_NOALPHA; |
7e0c58e9 | 178 | selEOLFilled = false; |
9e730a78 RD |
179 | |
180 | foldmarginColourSet = false; | |
181 | foldmarginColour.desired = ColourDesired(0xff, 0, 0); | |
182 | foldmarginHighlightColourSet = false; | |
183 | foldmarginHighlightColour.desired = ColourDesired(0xc0, 0xc0, 0xc0); | |
184 | ||
f114b858 RD |
185 | whitespaceForegroundSet = false; |
186 | whitespaceForeground.desired = ColourDesired(0, 0, 0); | |
187 | whitespaceBackgroundSet = false; | |
188 | whitespaceBackground.desired = ColourDesired(0xff, 0xff, 0xff); | |
9ce192d4 RD |
189 | selbar.desired = Platform::Chrome(); |
190 | selbarlight.desired = Platform::ChromeHighlight(); | |
1a2fb4cd | 191 | styles[STYLE_LINENUMBER].fore.desired = ColourDesired(0, 0, 0); |
9ce192d4 | 192 | styles[STYLE_LINENUMBER].back.desired = Platform::Chrome(); |
1a2fb4cd | 193 | caretcolour.desired = ColourDesired(0, 0, 0); |
65ec6247 | 194 | showCaretLineBackground = false; |
1a2fb4cd | 195 | caretLineBackground.desired = ColourDesired(0xff, 0xff, 0); |
b8193d80 | 196 | caretLineAlpha = SC_ALPHA_NOALPHA; |
1a2fb4cd | 197 | edgecolour.desired = ColourDesired(0xc0, 0xc0, 0xc0); |
d134f170 | 198 | edgeState = EDGE_NONE; |
7e0c58e9 | 199 | caretStyle = CARETSTYLE_LINE; |
65ec6247 | 200 | caretWidth = 1; |
9e730a78 RD |
201 | someStylesProtected = false; |
202 | ||
203 | hotspotForegroundSet = false; | |
204 | hotspotForeground.desired = ColourDesired(0, 0, 0xff); | |
205 | hotspotBackgroundSet = false; | |
206 | hotspotBackground.desired = ColourDesired(0xff, 0xff, 0xff); | |
207 | hotspotUnderline = true; | |
8e54aaed | 208 | hotspotSingleLine = true; |
65ec6247 | 209 | |
9ce192d4 RD |
210 | leftMarginWidth = 1; |
211 | rightMarginWidth = 1; | |
b8193d80 | 212 | ms[0].style = SC_MARGIN_NUMBER; |
9ce192d4 RD |
213 | ms[0].width = 0; |
214 | ms[0].mask = 0; | |
b8193d80 | 215 | ms[1].style = SC_MARGIN_SYMBOL; |
9ce192d4 RD |
216 | ms[1].width = 16; |
217 | ms[1].mask = ~SC_MASK_FOLDERS; | |
b8193d80 | 218 | ms[2].style = SC_MARGIN_SYMBOL; |
9e730a78 | 219 | ms[2].width = 0; |
9ce192d4 RD |
220 | ms[2].mask = 0; |
221 | fixedColumnWidth = leftMarginWidth; | |
222 | symbolMargin = false; | |
223 | maskInLine = 0xffffffff; | |
224 | for (int margin=0; margin < margins; margin++) { | |
225 | fixedColumnWidth += ms[margin].width; | |
b8193d80 | 226 | symbolMargin = symbolMargin || (ms[margin].style != SC_MARGIN_NUMBER); |
9ce192d4 RD |
227 | if (ms[margin].width > 0) |
228 | maskInLine &= ~ms[margin].mask; | |
229 | } | |
230 | zoomLevel = 0; | |
d134f170 | 231 | viewWhitespace = wsInvisible; |
7e0c58e9 | 232 | viewIndentationGuides = ivNone; |
9ce192d4 RD |
233 | viewEOL = false; |
234 | showMarkedLines = true; | |
591d01be | 235 | extraFontFlag = false; |
9ce192d4 RD |
236 | } |
237 | ||
238 | void ViewStyle::RefreshColourPalette(Palette &pal, bool want) { | |
239 | unsigned int i; | |
7e0c58e9 | 240 | for (i=0;i<stylesSize;i++) { |
9ce192d4 RD |
241 | pal.WantFind(styles[i].fore, want); |
242 | pal.WantFind(styles[i].back, want); | |
243 | } | |
244 | for (i=0;i<(sizeof(indicators)/sizeof(indicators[0]));i++) { | |
245 | pal.WantFind(indicators[i].fore, want); | |
246 | } | |
247 | for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) { | |
9e730a78 | 248 | markers[i].RefreshColourPalette(pal, want); |
9ce192d4 RD |
249 | } |
250 | pal.WantFind(selforeground, want); | |
251 | pal.WantFind(selbackground, want); | |
d134f170 | 252 | pal.WantFind(selbackground2, want); |
9e730a78 RD |
253 | |
254 | pal.WantFind(foldmarginColour, want); | |
255 | pal.WantFind(foldmarginHighlightColour, want); | |
256 | ||
f114b858 RD |
257 | pal.WantFind(whitespaceForeground, want); |
258 | pal.WantFind(whitespaceBackground, want); | |
9ce192d4 RD |
259 | pal.WantFind(selbar, want); |
260 | pal.WantFind(selbarlight, want); | |
261 | pal.WantFind(caretcolour, want); | |
65ec6247 | 262 | pal.WantFind(caretLineBackground, want); |
9ce192d4 | 263 | pal.WantFind(edgecolour, want); |
9e730a78 RD |
264 | pal.WantFind(hotspotForeground, want); |
265 | pal.WantFind(hotspotBackground, want); | |
9ce192d4 RD |
266 | } |
267 | ||
268 | void ViewStyle::Refresh(Surface &surface) { | |
269 | selbar.desired = Platform::Chrome(); | |
270 | selbarlight.desired = Platform::ChromeHighlight(); | |
e0e5663f | 271 | styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag); |
f6bcfd97 BP |
272 | maxAscent = styles[STYLE_DEFAULT].ascent; |
273 | maxDescent = styles[STYLE_DEFAULT].descent; | |
9e730a78 | 274 | someStylesProtected = false; |
7e0c58e9 | 275 | for (unsigned int i=0; i<stylesSize; i++) { |
f6bcfd97 | 276 | if (i != STYLE_DEFAULT) { |
e0e5663f | 277 | styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag); |
f6bcfd97 BP |
278 | if (maxAscent < styles[i].ascent) |
279 | maxAscent = styles[i].ascent; | |
280 | if (maxDescent < styles[i].descent) | |
281 | maxDescent = styles[i].descent; | |
282 | } | |
9e730a78 RD |
283 | if (styles[i].IsProtected()) { |
284 | someStylesProtected = true; | |
285 | } | |
9ce192d4 | 286 | } |
65ec6247 | 287 | |
9ce192d4 RD |
288 | lineHeight = maxAscent + maxDescent; |
289 | aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth; | |
290 | spaceWidth = styles[STYLE_DEFAULT].spaceWidth; | |
291 | ||
292 | fixedColumnWidth = leftMarginWidth; | |
293 | symbolMargin = false; | |
294 | maskInLine = 0xffffffff; | |
295 | for (int margin=0; margin < margins; margin++) { | |
296 | fixedColumnWidth += ms[margin].width; | |
b8193d80 | 297 | symbolMargin = symbolMargin || (ms[margin].style != SC_MARGIN_NUMBER); |
9ce192d4 RD |
298 | if (ms[margin].width > 0) |
299 | maskInLine &= ~ms[margin].mask; | |
300 | } | |
301 | } | |
302 | ||
7e0c58e9 RD |
303 | void ViewStyle::AllocStyles(size_t sizeNew) { |
304 | Style *stylesNew = new Style[sizeNew]; | |
305 | size_t i=0; | |
306 | for (; i<stylesSize; i++) { | |
307 | stylesNew[i] = styles[i]; | |
308 | stylesNew[i].fontName = styles[i].fontName; | |
309 | } | |
310 | if (stylesSize > STYLE_DEFAULT) { | |
311 | for (; i<sizeNew; i++) { | |
312 | if (i != STYLE_DEFAULT) { | |
313 | stylesNew[i].ClearTo(styles[STYLE_DEFAULT]); | |
314 | } | |
315 | } | |
316 | } | |
317 | delete []styles; | |
318 | styles = stylesNew; | |
319 | stylesSize = sizeNew; | |
320 | } | |
321 | ||
322 | void ViewStyle::EnsureStyle(size_t index) { | |
323 | if (index >= stylesSize) { | |
324 | size_t sizeNew = stylesSize * 2; | |
325 | while (sizeNew < index) | |
326 | sizeNew *= 2; | |
327 | AllocStyles(sizeNew); | |
328 | } | |
329 | } | |
330 | ||
9ce192d4 | 331 | void ViewStyle::ResetDefaultStyle() { |
9e730a78 | 332 | styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), |
1a2fb4cd | 333 | ColourDesired(0xff,0xff,0xff), |
7e0c58e9 | 334 | Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()), |
f6bcfd97 | 335 | SC_CHARSET_DEFAULT, |
9e730a78 | 336 | false, false, false, false, Style::caseMixed, true, true, false); |
9ce192d4 RD |
337 | } |
338 | ||
339 | void ViewStyle::ClearStyles() { | |
340 | // Reset all styles to be like the default style | |
7e0c58e9 | 341 | for (unsigned int i=0; i<stylesSize; i++) { |
9ce192d4 | 342 | if (i != STYLE_DEFAULT) { |
65ec6247 | 343 | styles[i].ClearTo(styles[STYLE_DEFAULT]); |
9ce192d4 RD |
344 | } |
345 | } | |
346 | styles[STYLE_LINENUMBER].back.desired = Platform::Chrome(); | |
b8193d80 RD |
347 | |
348 | // Set call tip fore/back to match the values previously set for call tips | |
349 | styles[STYLE_CALLTIP].back.desired = ColourDesired(0xff, 0xff, 0xff); | |
350 | styles[STYLE_CALLTIP].fore.desired = ColourDesired(0x80, 0x80, 0x80); | |
9ce192d4 RD |
351 | } |
352 | ||
f6bcfd97 BP |
353 | void ViewStyle::SetStyleFontName(int styleIndex, const char *name) { |
354 | styles[styleIndex].fontName = fontNames.Save(name); | |
355 | } | |
9e730a78 RD |
356 | |
357 | bool ViewStyle::ProtectionActive() const { | |
7e0c58e9 | 358 | return someStylesProtected; |
9e730a78 | 359 | } |