1 // Scintilla source code edit control
2 /** @file ViewStyle.cxx
3 ** Store information on how the document is to be viewed.
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
12 #include "Scintilla.h"
13 #include "SplitVector.h"
14 #include "Partitioning.h"
15 #include "RunStyles.h"
16 #include "Indicator.h"
18 #include "LineMarker.h"
20 #include "ViewStyle.h"
23 using namespace Scintilla
;
26 MarginStyle::MarginStyle() :
27 style(SC_MARGIN_SYMBOL
), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW
) {
30 // A list of the fontnames - avoids wasting space in each style
31 FontNames::FontNames() {
33 names
= new char *[size
];
37 FontNames::~FontNames() {
43 void FontNames::Clear() {
44 for (int i
=0; i
<max
; i
++) {
50 const char *FontNames::Save(const char *name
) {
53 for (int i
=0; i
<max
; i
++) {
54 if (strcmp(names
[i
], name
) == 0) {
60 int sizeNew
= size
* 2;
61 char **namesNew
= new char *[sizeNew
];
62 for (int j
=0; j
<max
; j
++) {
63 namesNew
[j
] = names
[j
];
69 names
[max
] = new char[strlen(name
) + 1];
70 strcpy(names
[max
], name
);
75 FontRealised::FontRealised(const FontSpecification
&fs
) {
77 (FontSpecification
&)(*this) = fs
;
80 FontRealised::~FontRealised() {
85 void FontRealised::Realise(Surface
&surface
, int zoomLevel
) {
86 PLATFORM_ASSERT(fontName
);
87 sizeZoomed
= size
+ zoomLevel
;
88 if (sizeZoomed
<= 2) // Hangs if sizeZoomed <= 1
91 int deviceHeight
= surface
.DeviceHeightFont(sizeZoomed
);
92 font
.Create(fontName
, characterSet
, deviceHeight
, bold
, italic
, extraFontFlag
);
94 ascent
= surface
.Ascent(font
);
95 descent
= surface
.Descent(font
);
96 externalLeading
= surface
.ExternalLeading(font
);
97 lineHeight
= surface
.Height(font
);
98 aveCharWidth
= surface
.AverageCharWidth(font
);
99 spaceWidth
= surface
.WidthChar(font
, ' ');
101 frNext
->Realise(surface
, zoomLevel
);
105 FontRealised
*FontRealised::Find(const FontSpecification
&fs
) {
108 FontRealised
*fr
= this;
117 void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent
, unsigned int &maxDescent
) {
118 FontRealised
*fr
= this;
120 if (maxAscent
< fr
->ascent
)
121 maxAscent
= fr
->ascent
;
122 if (maxDescent
< fr
->descent
)
123 maxDescent
= fr
->descent
;
128 ViewStyle::ViewStyle() {
132 ViewStyle::ViewStyle(const ViewStyle
&source
) {
134 Init(source
.stylesSize
);
135 for (unsigned int sty
=0; sty
<source
.stylesSize
; sty
++) {
136 styles
[sty
] = source
.styles
[sty
];
137 // Can't just copy fontname as its lifetime is relative to its owning ViewStyle
138 styles
[sty
].fontName
= fontNames
.Save(source
.styles
[sty
].fontName
);
140 for (int mrk
=0; mrk
<=MARKER_MAX
; mrk
++) {
141 markers
[mrk
] = source
.markers
[mrk
];
143 for (int ind
=0; ind
<=INDIC_MAX
; ind
++) {
144 indicators
[ind
] = source
.indicators
[ind
];
147 selforeset
= source
.selforeset
;
148 selforeground
.desired
= source
.selforeground
.desired
;
149 selAdditionalForeground
.desired
= source
.selAdditionalForeground
.desired
;
150 selbackset
= source
.selbackset
;
151 selbackground
.desired
= source
.selbackground
.desired
;
152 selAdditionalBackground
.desired
= source
.selAdditionalBackground
.desired
;
153 selbackground2
.desired
= source
.selbackground2
.desired
;
154 selAlpha
= source
.selAlpha
;
155 selAdditionalAlpha
= source
.selAdditionalAlpha
;
156 selEOLFilled
= source
.selEOLFilled
;
158 foldmarginColourSet
= source
.foldmarginColourSet
;
159 foldmarginColour
.desired
= source
.foldmarginColour
.desired
;
160 foldmarginHighlightColourSet
= source
.foldmarginHighlightColourSet
;
161 foldmarginHighlightColour
.desired
= source
.foldmarginHighlightColour
.desired
;
163 hotspotForegroundSet
= source
.hotspotForegroundSet
;
164 hotspotForeground
.desired
= source
.hotspotForeground
.desired
;
165 hotspotBackgroundSet
= source
.hotspotBackgroundSet
;
166 hotspotBackground
.desired
= source
.hotspotBackground
.desired
;
167 hotspotUnderline
= source
.hotspotUnderline
;
168 hotspotSingleLine
= source
.hotspotSingleLine
;
170 whitespaceForegroundSet
= source
.whitespaceForegroundSet
;
171 whitespaceForeground
.desired
= source
.whitespaceForeground
.desired
;
172 whitespaceBackgroundSet
= source
.whitespaceBackgroundSet
;
173 whitespaceBackground
.desired
= source
.whitespaceBackground
.desired
;
174 selbar
.desired
= source
.selbar
.desired
;
175 selbarlight
.desired
= source
.selbarlight
.desired
;
176 caretcolour
.desired
= source
.caretcolour
.desired
;
177 additionalCaretColour
.desired
= source
.additionalCaretColour
.desired
;
178 showCaretLineBackground
= source
.showCaretLineBackground
;
179 caretLineBackground
.desired
= source
.caretLineBackground
.desired
;
180 caretLineAlpha
= source
.caretLineAlpha
;
181 edgecolour
.desired
= source
.edgecolour
.desired
;
182 edgeState
= source
.edgeState
;
183 caretStyle
= source
.caretStyle
;
184 caretWidth
= source
.caretWidth
;
185 someStylesProtected
= false;
186 someStylesForceCase
= false;
187 leftMarginWidth
= source
.leftMarginWidth
;
188 rightMarginWidth
= source
.rightMarginWidth
;
189 for (int i
=0; i
< margins
; i
++) {
190 ms
[i
] = source
.ms
[i
];
192 symbolMargin
= source
.symbolMargin
;
193 maskInLine
= source
.maskInLine
;
194 fixedColumnWidth
= source
.fixedColumnWidth
;
195 zoomLevel
= source
.zoomLevel
;
196 viewWhitespace
= source
.viewWhitespace
;
197 whitespaceSize
= source
.whitespaceSize
;
198 viewIndentationGuides
= source
.viewIndentationGuides
;
199 viewEOL
= source
.viewEOL
;
200 showMarkedLines
= source
.showMarkedLines
;
201 extraFontFlag
= source
.extraFontFlag
;
202 extraAscent
= source
.extraAscent
;
203 extraDescent
= source
.extraDescent
;
204 marginStyleOffset
= source
.marginStyleOffset
;
205 annotationVisible
= source
.annotationVisible
;
206 annotationStyleOffset
= source
.annotationStyleOffset
;
207 braceHighlightIndicatorSet
= source
.braceHighlightIndicatorSet
;
208 braceHighlightIndicator
= source
.braceHighlightIndicator
;
209 braceBadLightIndicatorSet
= source
.braceBadLightIndicatorSet
;
210 braceBadLightIndicator
= source
.braceBadLightIndicator
;
213 ViewStyle::~ViewStyle() {
220 void ViewStyle::Init(size_t stylesSize_
) {
224 AllocStyles(stylesSize_
);
228 indicators
[0].style
= INDIC_SQUIGGLE
;
229 indicators
[0].under
= false;
230 indicators
[0].fore
= ColourDesired(0, 0x7f, 0);
231 indicators
[1].style
= INDIC_TT
;
232 indicators
[1].under
= false;
233 indicators
[1].fore
= ColourDesired(0, 0, 0xff);
234 indicators
[2].style
= INDIC_PLAIN
;
235 indicators
[2].under
= false;
236 indicators
[2].fore
= ColourDesired(0xff, 0, 0);
245 selforeground
.desired
= ColourDesired(0xff, 0, 0);
246 selAdditionalForeground
.desired
= ColourDesired(0xff, 0, 0);
248 selbackground
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
249 selAdditionalBackground
.desired
= ColourDesired(0xd7, 0xd7, 0xd7);
250 selbackground2
.desired
= ColourDesired(0xb0, 0xb0, 0xb0);
251 selAlpha
= SC_ALPHA_NOALPHA
;
252 selAdditionalAlpha
= SC_ALPHA_NOALPHA
;
253 selEOLFilled
= false;
255 foldmarginColourSet
= false;
256 foldmarginColour
.desired
= ColourDesired(0xff, 0, 0);
257 foldmarginHighlightColourSet
= false;
258 foldmarginHighlightColour
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
260 whitespaceForegroundSet
= false;
261 whitespaceForeground
.desired
= ColourDesired(0, 0, 0);
262 whitespaceBackgroundSet
= false;
263 whitespaceBackground
.desired
= ColourDesired(0xff, 0xff, 0xff);
264 selbar
.desired
= Platform::Chrome();
265 selbarlight
.desired
= Platform::ChromeHighlight();
266 styles
[STYLE_LINENUMBER
].fore
.desired
= ColourDesired(0, 0, 0);
267 styles
[STYLE_LINENUMBER
].back
.desired
= Platform::Chrome();
268 caretcolour
.desired
= ColourDesired(0, 0, 0);
269 additionalCaretColour
.desired
= ColourDesired(0x7f, 0x7f, 0x7f);
270 showCaretLineBackground
= false;
271 caretLineBackground
.desired
= ColourDesired(0xff, 0xff, 0);
272 caretLineAlpha
= SC_ALPHA_NOALPHA
;
273 edgecolour
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
274 edgeState
= EDGE_NONE
;
275 caretStyle
= CARETSTYLE_LINE
;
277 someStylesProtected
= false;
278 someStylesForceCase
= false;
280 hotspotForegroundSet
= false;
281 hotspotForeground
.desired
= ColourDesired(0, 0, 0xff);
282 hotspotBackgroundSet
= false;
283 hotspotBackground
.desired
= ColourDesired(0xff, 0xff, 0xff);
284 hotspotUnderline
= true;
285 hotspotSingleLine
= true;
288 rightMarginWidth
= 1;
289 ms
[0].style
= SC_MARGIN_NUMBER
;
292 ms
[1].style
= SC_MARGIN_SYMBOL
;
294 ms
[1].mask
= ~SC_MASK_FOLDERS
;
295 ms
[2].style
= SC_MARGIN_SYMBOL
;
298 fixedColumnWidth
= leftMarginWidth
;
299 symbolMargin
= false;
300 maskInLine
= 0xffffffff;
301 for (int margin
=0; margin
< margins
; margin
++) {
302 fixedColumnWidth
+= ms
[margin
].width
;
303 symbolMargin
= symbolMargin
|| (ms
[margin
].style
!= SC_MARGIN_NUMBER
);
304 if (ms
[margin
].width
> 0)
305 maskInLine
&= ~ms
[margin
].mask
;
308 viewWhitespace
= wsInvisible
;
310 viewIndentationGuides
= ivNone
;
312 showMarkedLines
= true;
316 marginStyleOffset
= 0;
317 annotationVisible
= ANNOTATION_HIDDEN
;
318 annotationStyleOffset
= 0;
319 braceHighlightIndicatorSet
= false;
320 braceHighlightIndicator
= 0;
321 braceBadLightIndicatorSet
= false;
322 braceBadLightIndicator
= 0;
325 void ViewStyle::RefreshColourPalette(Palette
&pal
, bool want
) {
327 for (i
=0; i
<stylesSize
; i
++) {
328 pal
.WantFind(styles
[i
].fore
, want
);
329 pal
.WantFind(styles
[i
].back
, want
);
331 for (i
=0; i
<(sizeof(indicators
)/sizeof(indicators
[0])); i
++) {
332 pal
.WantFind(indicators
[i
].fore
, want
);
334 for (i
=0; i
<(sizeof(markers
)/sizeof(markers
[0])); i
++) {
335 markers
[i
].RefreshColourPalette(pal
, want
);
337 pal
.WantFind(selforeground
, want
);
338 pal
.WantFind(selAdditionalForeground
, want
);
339 pal
.WantFind(selbackground
, want
);
340 pal
.WantFind(selAdditionalBackground
, want
);
341 pal
.WantFind(selbackground2
, want
);
343 pal
.WantFind(foldmarginColour
, want
);
344 pal
.WantFind(foldmarginHighlightColour
, want
);
346 pal
.WantFind(whitespaceForeground
, want
);
347 pal
.WantFind(whitespaceBackground
, want
);
348 pal
.WantFind(selbar
, want
);
349 pal
.WantFind(selbarlight
, want
);
350 pal
.WantFind(caretcolour
, want
);
351 pal
.WantFind(additionalCaretColour
, want
);
352 pal
.WantFind(caretLineBackground
, want
);
353 pal
.WantFind(edgecolour
, want
);
354 pal
.WantFind(hotspotForeground
, want
);
355 pal
.WantFind(hotspotBackground
, want
);
358 void ViewStyle::CreateFont(const FontSpecification
&fs
) {
360 for (FontRealised
*cur
=frFirst
; cur
; cur
=cur
->frNext
) {
361 if (cur
->EqualTo(fs
))
364 cur
->frNext
= new FontRealised(fs
);
368 frFirst
= new FontRealised(fs
);
372 void ViewStyle::Refresh(Surface
&surface
) {
375 selbar
.desired
= Platform::Chrome();
376 selbarlight
.desired
= Platform::ChromeHighlight();
378 for (unsigned int i
=0; i
<stylesSize
; i
++) {
379 styles
[i
].extraFontFlag
= extraFontFlag
;
382 CreateFont(styles
[STYLE_DEFAULT
]);
383 for (unsigned int j
=0; j
<stylesSize
; j
++) {
384 CreateFont(styles
[j
]);
387 frFirst
->Realise(surface
, zoomLevel
);
389 for (unsigned int k
=0; k
<stylesSize
; k
++) {
390 FontRealised
*fr
= frFirst
->Find(styles
[k
]);
391 styles
[k
].Copy(fr
->font
, *fr
);
395 frFirst
->FindMaxAscentDescent(maxAscent
, maxDescent
);
396 maxAscent
+= extraAscent
;
397 maxDescent
+= extraDescent
;
398 lineHeight
= maxAscent
+ maxDescent
;
400 someStylesProtected
= false;
401 someStylesForceCase
= false;
402 for (unsigned int l
=0; l
<stylesSize
; l
++) {
403 if (styles
[l
].IsProtected()) {
404 someStylesProtected
= true;
406 if (styles
[l
].caseForce
!= Style::caseMixed
) {
407 someStylesForceCase
= true;
411 aveCharWidth
= styles
[STYLE_DEFAULT
].aveCharWidth
;
412 spaceWidth
= styles
[STYLE_DEFAULT
].spaceWidth
;
414 fixedColumnWidth
= leftMarginWidth
;
415 symbolMargin
= false;
416 maskInLine
= 0xffffffff;
417 for (int margin
=0; margin
< margins
; margin
++) {
418 fixedColumnWidth
+= ms
[margin
].width
;
419 symbolMargin
= symbolMargin
|| (ms
[margin
].style
!= SC_MARGIN_NUMBER
);
420 if (ms
[margin
].width
> 0)
421 maskInLine
&= ~ms
[margin
].mask
;
425 void ViewStyle::AllocStyles(size_t sizeNew
) {
426 Style
*stylesNew
= new Style
[sizeNew
];
428 for (; i
<stylesSize
; i
++) {
429 stylesNew
[i
] = styles
[i
];
430 stylesNew
[i
].fontName
= styles
[i
].fontName
;
432 if (stylesSize
> STYLE_DEFAULT
) {
433 for (; i
<sizeNew
; i
++) {
434 if (i
!= STYLE_DEFAULT
) {
435 stylesNew
[i
].ClearTo(styles
[STYLE_DEFAULT
]);
441 stylesSize
= sizeNew
;
444 void ViewStyle::EnsureStyle(size_t index
) {
445 if (index
>= stylesSize
) {
446 size_t sizeNew
= stylesSize
* 2;
447 while (sizeNew
<= index
)
449 AllocStyles(sizeNew
);
453 void ViewStyle::ResetDefaultStyle() {
454 styles
[STYLE_DEFAULT
].Clear(ColourDesired(0,0,0),
455 ColourDesired(0xff,0xff,0xff),
456 Platform::DefaultFontSize(), fontNames
.Save(Platform::DefaultFont()),
458 false, false, false, false, Style::caseMixed
, true, true, false);
461 void ViewStyle::ClearStyles() {
462 // Reset all styles to be like the default style
463 for (unsigned int i
=0; i
<stylesSize
; i
++) {
464 if (i
!= STYLE_DEFAULT
) {
465 styles
[i
].ClearTo(styles
[STYLE_DEFAULT
]);
468 styles
[STYLE_LINENUMBER
].back
.desired
= Platform::Chrome();
470 // Set call tip fore/back to match the values previously set for call tips
471 styles
[STYLE_CALLTIP
].back
.desired
= ColourDesired(0xff, 0xff, 0xff);
472 styles
[STYLE_CALLTIP
].fore
.desired
= ColourDesired(0x80, 0x80, 0x80);
475 void ViewStyle::SetStyleFontName(int styleIndex
, const char *name
) {
476 styles
[styleIndex
].fontName
= fontNames
.Save(name
);
479 bool ViewStyle::ProtectionActive() const {
480 return someStylesProtected
;
483 bool ViewStyle::ValidStyle(size_t styleIndex
) const {
484 return styleIndex
< stylesSize
;