]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/src/ViewStyle.cxx
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / stc / scintilla / src / ViewStyle.cxx
CommitLineData
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
1dcf666d
RD
10#include <vector>
11#include <map>
12
9ce192d4
RD
13#include "Platform.h"
14
15#include "Scintilla.h"
7e0c58e9
RD
16#include "SplitVector.h"
17#include "Partitioning.h"
18#include "RunStyles.h"
9ce192d4 19#include "Indicator.h"
9e730a78 20#include "XPM.h"
9ce192d4
RD
21#include "LineMarker.h"
22#include "Style.h"
23#include "ViewStyle.h"
24
7e0c58e9
RD
25#ifdef SCI_NAMESPACE
26using namespace Scintilla;
27#endif
28
65ec6247 29MarginStyle::MarginStyle() :
1dcf666d 30 style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
9ce192d4
RD
31}
32
f6bcfd97
BP
33// A list of the fontnames - avoids wasting space in each style
34FontNames::FontNames() {
7e0c58e9
RD
35 size = 8;
36 names = new char *[size];
f6bcfd97
BP
37 max = 0;
38}
39
40FontNames::~FontNames() {
41 Clear();
7e0c58e9
RD
42 delete []names;
43 names = 0;
f6bcfd97
BP
44}
45
46void FontNames::Clear() {
1dcf666d 47 for (int i=0; i<max; i++) {
f6bcfd97
BP
48 delete []names[i];
49 }
50 max = 0;
51}
52
53const char *FontNames::Save(const char *name) {
54 if (!name)
55 return 0;
1dcf666d 56 for (int i=0; i<max; i++) {
f6bcfd97
BP
57 if (strcmp(names[i], name) == 0) {
58 return names[i];
59 }
60 }
7e0c58e9
RD
61 if (max >= size) {
62 // Grow array
63 int sizeNew = size * 2;
64 char **namesNew = new char *[sizeNew];
1dcf666d 65 for (int j=0; j<max; j++) {
7e0c58e9
RD
66 namesNew[j] = names[j];
67 }
68 delete []names;
69 names = namesNew;
70 size = sizeNew;
71 }
f6bcfd97
BP
72 names[max] = new char[strlen(name) + 1];
73 strcpy(names[max], name);
74 max++;
75 return names[max-1];
76}
77
1dcf666d
RD
78FontRealised::FontRealised(const FontSpecification &fs) {
79 frNext = NULL;
80 (FontSpecification &)(*this) = fs;
81}
82
83FontRealised::~FontRealised() {
84 font.Release();
85 delete frNext;
86 frNext = 0;
87}
88
89void FontRealised::Realise(Surface &surface, int zoomLevel, int technology) {
90 PLATFORM_ASSERT(fontName);
91 sizeZoomed = size + zoomLevel * SC_FONT_SIZE_MULTIPLIER;
92 if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1
93 sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER;
94
95 float deviceHeight = surface.DeviceHeightFont(sizeZoomed);
96 FontParameters fp(fontName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, weight, italic, extraFontFlag, technology, characterSet);
97 font.Create(fp);
98
99 ascent = surface.Ascent(font);
100 descent = surface.Descent(font);
101 aveCharWidth = surface.AverageCharWidth(font);
102 spaceWidth = surface.WidthChar(font, ' ');
103 if (frNext) {
104 frNext->Realise(surface, zoomLevel, technology);
105 }
106}
107
108FontRealised *FontRealised::Find(const FontSpecification &fs) {
109 if (!fs.fontName)
110 return this;
111 FontRealised *fr = this;
112 while (fr) {
113 if (fr->EqualTo(fs))
114 return fr;
115 fr = fr->frNext;
116 }
117 return 0;
118}
119
120void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
121 FontRealised *fr = this;
122 while (fr) {
123 if (maxAscent < fr->ascent)
124 maxAscent = fr->ascent;
125 if (maxDescent < fr->descent)
126 maxDescent = fr->descent;
127 fr = fr->frNext;
128 }
129}
130
9ce192d4
RD
131ViewStyle::ViewStyle() {
132 Init();
133}
134
135ViewStyle::ViewStyle(const ViewStyle &source) {
1dcf666d 136 frFirst = NULL;
7e0c58e9 137 Init(source.stylesSize);
1dcf666d 138 for (unsigned int sty=0; sty<source.stylesSize; sty++) {
9ce192d4 139 styles[sty] = source.styles[sty];
f6bcfd97
BP
140 // Can't just copy fontname as its lifetime is relative to its owning ViewStyle
141 styles[sty].fontName = fontNames.Save(source.styles[sty].fontName);
9ce192d4 142 }
1dcf666d 143 for (int mrk=0; mrk<=MARKER_MAX; mrk++) {
9ce192d4
RD
144 markers[mrk] = source.markers[mrk];
145 }
1dcf666d
RD
146 CalcLargestMarkerHeight();
147 for (int ind=0; ind<=INDIC_MAX; ind++) {
9ce192d4
RD
148 indicators[ind] = source.indicators[ind];
149 }
65ec6247 150
9ce192d4 151 selforeset = source.selforeset;
1dcf666d
RD
152 selforeground = source.selforeground;
153 selAdditionalForeground = source.selAdditionalForeground;
9ce192d4 154 selbackset = source.selbackset;
1dcf666d
RD
155 selbackground = source.selbackground;
156 selAdditionalBackground = source.selAdditionalBackground;
157 selbackground2 = source.selbackground2;
b8193d80 158 selAlpha = source.selAlpha;
9e96e16f 159 selAdditionalAlpha = source.selAdditionalAlpha;
7e0c58e9 160 selEOLFilled = source.selEOLFilled;
9e730a78
RD
161
162 foldmarginColourSet = source.foldmarginColourSet;
1dcf666d 163 foldmarginColour = source.foldmarginColour;
9e730a78 164 foldmarginHighlightColourSet = source.foldmarginHighlightColourSet;
1dcf666d 165 foldmarginHighlightColour = source.foldmarginHighlightColour;
9e730a78
RD
166
167 hotspotForegroundSet = source.hotspotForegroundSet;
1dcf666d 168 hotspotForeground = source.hotspotForeground;
9e730a78 169 hotspotBackgroundSet = source.hotspotBackgroundSet;
1dcf666d 170 hotspotBackground = source.hotspotBackground;
9e730a78 171 hotspotUnderline = source.hotspotUnderline;
8e54aaed 172 hotspotSingleLine = source.hotspotSingleLine;
9e730a78 173
f114b858 174 whitespaceForegroundSet = source.whitespaceForegroundSet;
1dcf666d 175 whitespaceForeground = source.whitespaceForeground;
f114b858 176 whitespaceBackgroundSet = source.whitespaceBackgroundSet;
1dcf666d
RD
177 whitespaceBackground = source.whitespaceBackground;
178 selbar = source.selbar;
179 selbarlight = source.selbarlight;
180 caretcolour = source.caretcolour;
181 additionalCaretColour = source.additionalCaretColour;
65ec6247 182 showCaretLineBackground = source.showCaretLineBackground;
1dcf666d 183 caretLineBackground = source.caretLineBackground;
b8193d80 184 caretLineAlpha = source.caretLineAlpha;
1dcf666d 185 edgecolour = source.edgecolour;
d134f170 186 edgeState = source.edgeState;
7e0c58e9 187 caretStyle = source.caretStyle;
65ec6247 188 caretWidth = source.caretWidth;
591d01be 189 someStylesProtected = false;
1dcf666d 190 someStylesForceCase = false;
9ce192d4
RD
191 leftMarginWidth = source.leftMarginWidth;
192 rightMarginWidth = source.rightMarginWidth;
1dcf666d 193 for (int i=0; i < margins; i++) {
9ce192d4
RD
194 ms[i] = source.ms[i];
195 }
9ce192d4
RD
196 maskInLine = source.maskInLine;
197 fixedColumnWidth = source.fixedColumnWidth;
198 zoomLevel = source.zoomLevel;
199 viewWhitespace = source.viewWhitespace;
9e96e16f 200 whitespaceSize = source.whitespaceSize;
d134f170 201 viewIndentationGuides = source.viewIndentationGuides;
9ce192d4 202 viewEOL = source.viewEOL;
591d01be 203 extraFontFlag = source.extraFontFlag;
9e96e16f
RD
204 extraAscent = source.extraAscent;
205 extraDescent = source.extraDescent;
206 marginStyleOffset = source.marginStyleOffset;
207 annotationVisible = source.annotationVisible;
208 annotationStyleOffset = source.annotationStyleOffset;
1dcf666d
RD
209 braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
210 braceHighlightIndicator = source.braceHighlightIndicator;
211 braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
212 braceBadLightIndicator = source.braceBadLightIndicator;
9ce192d4
RD
213}
214
215ViewStyle::~ViewStyle() {
7e0c58e9
RD
216 delete []styles;
217 styles = NULL;
1dcf666d
RD
218 delete frFirst;
219 frFirst = NULL;
9ce192d4
RD
220}
221
7e0c58e9 222void ViewStyle::Init(size_t stylesSize_) {
1dcf666d 223 frFirst = NULL;
7e0c58e9
RD
224 stylesSize = 0;
225 styles = NULL;
226 AllocStyles(stylesSize_);
f6bcfd97
BP
227 fontNames.Clear();
228 ResetDefaultStyle();
65ec6247 229
1dcf666d
RD
230 // There are no image markers by default, so no need for calling CalcLargestMarkerHeight()
231 largestMarkerHeight = 0;
232
9ce192d4 233 indicators[0].style = INDIC_SQUIGGLE;
7e0c58e9 234 indicators[0].under = false;
1a2fb4cd 235 indicators[0].fore = ColourDesired(0, 0x7f, 0);
9ce192d4 236 indicators[1].style = INDIC_TT;
7e0c58e9 237 indicators[1].under = false;
1a2fb4cd 238 indicators[1].fore = ColourDesired(0, 0, 0xff);
9ce192d4 239 indicators[2].style = INDIC_PLAIN;
7e0c58e9 240 indicators[2].under = false;
1a2fb4cd 241 indicators[2].fore = ColourDesired(0xff, 0, 0);
9ce192d4 242
1dcf666d 243 technology = SC_TECHNOLOGY_DEFAULT;
9ce192d4
RD
244 lineHeight = 1;
245 maxAscent = 1;
246 maxDescent = 1;
247 aveCharWidth = 8;
248 spaceWidth = 8;
249
250 selforeset = false;
1dcf666d
RD
251 selforeground = ColourDesired(0xff, 0, 0);
252 selAdditionalForeground = ColourDesired(0xff, 0, 0);
9ce192d4 253 selbackset = true;
1dcf666d
RD
254 selbackground = ColourDesired(0xc0, 0xc0, 0xc0);
255 selAdditionalBackground = ColourDesired(0xd7, 0xd7, 0xd7);
256 selbackground2 = ColourDesired(0xb0, 0xb0, 0xb0);
b8193d80 257 selAlpha = SC_ALPHA_NOALPHA;
9e96e16f 258 selAdditionalAlpha = SC_ALPHA_NOALPHA;
7e0c58e9 259 selEOLFilled = false;
9e730a78
RD
260
261 foldmarginColourSet = false;
1dcf666d 262 foldmarginColour = ColourDesired(0xff, 0, 0);
9e730a78 263 foldmarginHighlightColourSet = false;
1dcf666d 264 foldmarginHighlightColour = ColourDesired(0xc0, 0xc0, 0xc0);
9e730a78 265
f114b858 266 whitespaceForegroundSet = false;
1dcf666d 267 whitespaceForeground = ColourDesired(0, 0, 0);
f114b858 268 whitespaceBackgroundSet = false;
1dcf666d
RD
269 whitespaceBackground = ColourDesired(0xff, 0xff, 0xff);
270 selbar = Platform::Chrome();
271 selbarlight = Platform::ChromeHighlight();
272 styles[STYLE_LINENUMBER].fore = ColourDesired(0, 0, 0);
273 styles[STYLE_LINENUMBER].back = Platform::Chrome();
274 caretcolour = ColourDesired(0, 0, 0);
275 additionalCaretColour = ColourDesired(0x7f, 0x7f, 0x7f);
65ec6247 276 showCaretLineBackground = false;
1dcf666d 277 caretLineBackground = ColourDesired(0xff, 0xff, 0);
b8193d80 278 caretLineAlpha = SC_ALPHA_NOALPHA;
1dcf666d 279 edgecolour = ColourDesired(0xc0, 0xc0, 0xc0);
d134f170 280 edgeState = EDGE_NONE;
7e0c58e9 281 caretStyle = CARETSTYLE_LINE;
65ec6247 282 caretWidth = 1;
9e730a78 283 someStylesProtected = false;
1dcf666d 284 someStylesForceCase = false;
9e730a78
RD
285
286 hotspotForegroundSet = false;
1dcf666d 287 hotspotForeground = ColourDesired(0, 0, 0xff);
9e730a78 288 hotspotBackgroundSet = false;
1dcf666d 289 hotspotBackground = ColourDesired(0xff, 0xff, 0xff);
9e730a78 290 hotspotUnderline = true;
8e54aaed 291 hotspotSingleLine = true;
65ec6247 292
9ce192d4
RD
293 leftMarginWidth = 1;
294 rightMarginWidth = 1;
b8193d80 295 ms[0].style = SC_MARGIN_NUMBER;
9ce192d4
RD
296 ms[0].width = 0;
297 ms[0].mask = 0;
b8193d80 298 ms[1].style = SC_MARGIN_SYMBOL;
9ce192d4
RD
299 ms[1].width = 16;
300 ms[1].mask = ~SC_MASK_FOLDERS;
b8193d80 301 ms[2].style = SC_MARGIN_SYMBOL;
9e730a78 302 ms[2].width = 0;
9ce192d4
RD
303 ms[2].mask = 0;
304 fixedColumnWidth = leftMarginWidth;
9ce192d4
RD
305 maskInLine = 0xffffffff;
306 for (int margin=0; margin < margins; margin++) {
307 fixedColumnWidth += ms[margin].width;
9ce192d4
RD
308 if (ms[margin].width > 0)
309 maskInLine &= ~ms[margin].mask;
310 }
311 zoomLevel = 0;
d134f170 312 viewWhitespace = wsInvisible;
9e96e16f 313 whitespaceSize = 1;
7e0c58e9 314 viewIndentationGuides = ivNone;
9ce192d4 315 viewEOL = false;
9e96e16f
RD
316 extraFontFlag = 0;
317 extraAscent = 0;
318 extraDescent = 0;
319 marginStyleOffset = 0;
320 annotationVisible = ANNOTATION_HIDDEN;
321 annotationStyleOffset = 0;
1dcf666d
RD
322 braceHighlightIndicatorSet = false;
323 braceHighlightIndicator = 0;
324 braceBadLightIndicatorSet = false;
325 braceBadLightIndicator = 0;
9ce192d4
RD
326}
327
1dcf666d
RD
328void ViewStyle::CreateFont(const FontSpecification &fs) {
329 if (fs.fontName) {
330 for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
331 if (cur->EqualTo(fs))
332 return;
333 if (!cur->frNext) {
334 cur->frNext = new FontRealised(fs);
335 return;
336 }
337 }
338 frFirst = new FontRealised(fs);
9ce192d4 339 }
9ce192d4
RD
340}
341
342void ViewStyle::Refresh(Surface &surface) {
1dcf666d
RD
343 delete frFirst;
344 frFirst = NULL;
345 selbar = Platform::Chrome();
346 selbarlight = Platform::ChromeHighlight();
347
7e0c58e9 348 for (unsigned int i=0; i<stylesSize; i++) {
1dcf666d 349 styles[i].extraFontFlag = extraFontFlag;
9ce192d4 350 }
1dcf666d
RD
351
352 CreateFont(styles[STYLE_DEFAULT]);
353 for (unsigned int j=0; j<stylesSize; j++) {
354 CreateFont(styles[j]);
355 }
356
357 frFirst->Realise(surface, zoomLevel, technology);
358
359 for (unsigned int k=0; k<stylesSize; k++) {
360 FontRealised *fr = frFirst->Find(styles[k]);
361 styles[k].Copy(fr->font, *fr);
362 }
363 maxAscent = 1;
364 maxDescent = 1;
365 frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
9e96e16f
RD
366 maxAscent += extraAscent;
367 maxDescent += extraDescent;
9ce192d4 368 lineHeight = maxAscent + maxDescent;
1dcf666d
RD
369
370 someStylesProtected = false;
371 someStylesForceCase = false;
372 for (unsigned int l=0; l<stylesSize; l++) {
373 if (styles[l].IsProtected()) {
374 someStylesProtected = true;
375 }
376 if (styles[l].caseForce != Style::caseMixed) {
377 someStylesForceCase = true;
378 }
379 }
380
9ce192d4
RD
381 aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
382 spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
383
384 fixedColumnWidth = leftMarginWidth;
9ce192d4
RD
385 maskInLine = 0xffffffff;
386 for (int margin=0; margin < margins; margin++) {
387 fixedColumnWidth += ms[margin].width;
9ce192d4
RD
388 if (ms[margin].width > 0)
389 maskInLine &= ~ms[margin].mask;
390 }
391}
392
7e0c58e9
RD
393void ViewStyle::AllocStyles(size_t sizeNew) {
394 Style *stylesNew = new Style[sizeNew];
395 size_t i=0;
396 for (; i<stylesSize; i++) {
397 stylesNew[i] = styles[i];
398 stylesNew[i].fontName = styles[i].fontName;
399 }
400 if (stylesSize > STYLE_DEFAULT) {
401 for (; i<sizeNew; i++) {
402 if (i != STYLE_DEFAULT) {
403 stylesNew[i].ClearTo(styles[STYLE_DEFAULT]);
404 }
405 }
406 }
407 delete []styles;
408 styles = stylesNew;
409 stylesSize = sizeNew;
410}
411
412void ViewStyle::EnsureStyle(size_t index) {
413 if (index >= stylesSize) {
414 size_t sizeNew = stylesSize * 2;
9e96e16f 415 while (sizeNew <= index)
7e0c58e9
RD
416 sizeNew *= 2;
417 AllocStyles(sizeNew);
418 }
419}
420
9ce192d4 421void ViewStyle::ResetDefaultStyle() {
9e730a78 422 styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
1dcf666d
RD
423 ColourDesired(0xff,0xff,0xff),
424 Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, fontNames.Save(Platform::DefaultFont()),
425 SC_CHARSET_DEFAULT,
426 SC_WEIGHT_NORMAL, false, false, false, Style::caseMixed, true, true, false);
9ce192d4
RD
427}
428
429void ViewStyle::ClearStyles() {
430 // Reset all styles to be like the default style
7e0c58e9 431 for (unsigned int i=0; i<stylesSize; i++) {
9ce192d4 432 if (i != STYLE_DEFAULT) {
65ec6247 433 styles[i].ClearTo(styles[STYLE_DEFAULT]);
9ce192d4
RD
434 }
435 }
1dcf666d 436 styles[STYLE_LINENUMBER].back = Platform::Chrome();
b8193d80
RD
437
438 // Set call tip fore/back to match the values previously set for call tips
1dcf666d
RD
439 styles[STYLE_CALLTIP].back = ColourDesired(0xff, 0xff, 0xff);
440 styles[STYLE_CALLTIP].fore = ColourDesired(0x80, 0x80, 0x80);
9ce192d4
RD
441}
442
f6bcfd97
BP
443void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
444 styles[styleIndex].fontName = fontNames.Save(name);
445}
9e730a78
RD
446
447bool ViewStyle::ProtectionActive() const {
7e0c58e9 448 return someStylesProtected;
9e730a78 449}
9e96e16f
RD
450
451bool ViewStyle::ValidStyle(size_t styleIndex) const {
452 return styleIndex < stylesSize;
453}
454
1dcf666d
RD
455void ViewStyle::CalcLargestMarkerHeight() {
456 largestMarkerHeight = 0;
457 for (int m = 0; m <= MARKER_MAX; ++m) {
458 switch (markers[m].markType) {
459 case SC_MARK_PIXMAP:
460 if (markers[m].pxpm->GetHeight() > largestMarkerHeight)
461 largestMarkerHeight = markers[m].pxpm->GetHeight();
462 break;
463 case SC_MARK_RGBAIMAGE:
464 if (markers[m].image->GetHeight() > largestMarkerHeight)
465 largestMarkerHeight = markers[m].image->GetHeight();
466 break;
467 }
468 }
469}
470