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.
15 #include "Scintilla.h"
16 #include "SplitVector.h"
17 #include "Partitioning.h"
18 #include "RunStyles.h"
19 #include "Indicator.h"
21 #include "LineMarker.h"
23 #include "ViewStyle.h"
26 using namespace Scintilla
;
29 MarginStyle::MarginStyle() :
30 style(SC_MARGIN_SYMBOL
), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW
) {
33 // A list of the fontnames - avoids wasting space in each style
34 FontNames::FontNames() {
36 names
= new char *[size
];
40 FontNames::~FontNames() {
46 void FontNames::Clear() {
47 for (int i
=0; i
<max
; i
++) {
53 const char *FontNames::Save(const char *name
) {
56 for (int i
=0; i
<max
; i
++) {
57 if (strcmp(names
[i
], name
) == 0) {
63 int sizeNew
= size
* 2;
64 char **namesNew
= new char *[sizeNew
];
65 for (int j
=0; j
<max
; j
++) {
66 namesNew
[j
] = names
[j
];
72 names
[max
] = new char[strlen(name
) + 1];
73 strcpy(names
[max
], name
);
78 FontRealised::FontRealised(const FontSpecification
&fs
) {
80 (FontSpecification
&)(*this) = fs
;
83 FontRealised::~FontRealised() {
89 void FontRealised::Realise(Surface
&surface
, int zoomLevel
) {
90 PLATFORM_ASSERT(fontName
);
91 sizeZoomed
= size
+ zoomLevel
;
92 if (sizeZoomed
<= 2) // Hangs if sizeZoomed <= 1
95 int deviceHeight
= surface
.DeviceHeightFont(sizeZoomed
);
96 font
.Create(fontName
, characterSet
, deviceHeight
, bold
, italic
, extraFontFlag
);
98 ascent
= surface
.Ascent(font
);
99 descent
= surface
.Descent(font
);
100 externalLeading
= surface
.ExternalLeading(font
);
101 lineHeight
= surface
.Height(font
);
102 aveCharWidth
= surface
.AverageCharWidth(font
);
103 spaceWidth
= surface
.WidthChar(font
, ' ');
105 frNext
->Realise(surface
, zoomLevel
);
109 FontRealised
*FontRealised::Find(const FontSpecification
&fs
) {
112 FontRealised
*fr
= this;
121 void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent
, unsigned int &maxDescent
) {
122 FontRealised
*fr
= this;
124 if (maxAscent
< fr
->ascent
)
125 maxAscent
= fr
->ascent
;
126 if (maxDescent
< fr
->descent
)
127 maxDescent
= fr
->descent
;
132 ViewStyle::ViewStyle() {
136 ViewStyle::ViewStyle(const ViewStyle
&source
) {
138 Init(source
.stylesSize
);
139 for (unsigned int sty
=0; sty
<source
.stylesSize
; sty
++) {
140 styles
[sty
] = source
.styles
[sty
];
141 // Can't just copy fontname as its lifetime is relative to its owning ViewStyle
142 styles
[sty
].fontName
= fontNames
.Save(source
.styles
[sty
].fontName
);
144 for (int mrk
=0; mrk
<=MARKER_MAX
; mrk
++) {
145 markers
[mrk
] = source
.markers
[mrk
];
147 for (int ind
=0; ind
<=INDIC_MAX
; ind
++) {
148 indicators
[ind
] = source
.indicators
[ind
];
151 selforeset
= source
.selforeset
;
152 selforeground
.desired
= source
.selforeground
.desired
;
153 selAdditionalForeground
.desired
= source
.selAdditionalForeground
.desired
;
154 selbackset
= source
.selbackset
;
155 selbackground
.desired
= source
.selbackground
.desired
;
156 selAdditionalBackground
.desired
= source
.selAdditionalBackground
.desired
;
157 selbackground2
.desired
= source
.selbackground2
.desired
;
158 selAlpha
= source
.selAlpha
;
159 selAdditionalAlpha
= source
.selAdditionalAlpha
;
160 selEOLFilled
= source
.selEOLFilled
;
162 foldmarginColourSet
= source
.foldmarginColourSet
;
163 foldmarginColour
.desired
= source
.foldmarginColour
.desired
;
164 foldmarginHighlightColourSet
= source
.foldmarginHighlightColourSet
;
165 foldmarginHighlightColour
.desired
= source
.foldmarginHighlightColour
.desired
;
167 hotspotForegroundSet
= source
.hotspotForegroundSet
;
168 hotspotForeground
.desired
= source
.hotspotForeground
.desired
;
169 hotspotBackgroundSet
= source
.hotspotBackgroundSet
;
170 hotspotBackground
.desired
= source
.hotspotBackground
.desired
;
171 hotspotUnderline
= source
.hotspotUnderline
;
172 hotspotSingleLine
= source
.hotspotSingleLine
;
174 whitespaceForegroundSet
= source
.whitespaceForegroundSet
;
175 whitespaceForeground
.desired
= source
.whitespaceForeground
.desired
;
176 whitespaceBackgroundSet
= source
.whitespaceBackgroundSet
;
177 whitespaceBackground
.desired
= source
.whitespaceBackground
.desired
;
178 selbar
.desired
= source
.selbar
.desired
;
179 selbarlight
.desired
= source
.selbarlight
.desired
;
180 caretcolour
.desired
= source
.caretcolour
.desired
;
181 additionalCaretColour
.desired
= source
.additionalCaretColour
.desired
;
182 showCaretLineBackground
= source
.showCaretLineBackground
;
183 caretLineBackground
.desired
= source
.caretLineBackground
.desired
;
184 caretLineAlpha
= source
.caretLineAlpha
;
185 edgecolour
.desired
= source
.edgecolour
.desired
;
186 edgeState
= source
.edgeState
;
187 caretStyle
= source
.caretStyle
;
188 caretWidth
= source
.caretWidth
;
189 someStylesProtected
= false;
190 someStylesForceCase
= false;
191 leftMarginWidth
= source
.leftMarginWidth
;
192 rightMarginWidth
= source
.rightMarginWidth
;
193 for (int i
=0; i
< margins
; i
++) {
194 ms
[i
] = source
.ms
[i
];
196 symbolMargin
= source
.symbolMargin
;
197 maskInLine
= source
.maskInLine
;
198 fixedColumnWidth
= source
.fixedColumnWidth
;
199 zoomLevel
= source
.zoomLevel
;
200 viewWhitespace
= source
.viewWhitespace
;
201 whitespaceSize
= source
.whitespaceSize
;
202 viewIndentationGuides
= source
.viewIndentationGuides
;
203 viewEOL
= source
.viewEOL
;
204 showMarkedLines
= source
.showMarkedLines
;
205 extraFontFlag
= source
.extraFontFlag
;
206 extraAscent
= source
.extraAscent
;
207 extraDescent
= source
.extraDescent
;
208 marginStyleOffset
= source
.marginStyleOffset
;
209 annotationVisible
= source
.annotationVisible
;
210 annotationStyleOffset
= source
.annotationStyleOffset
;
211 braceHighlightIndicatorSet
= source
.braceHighlightIndicatorSet
;
212 braceHighlightIndicator
= source
.braceHighlightIndicator
;
213 braceBadLightIndicatorSet
= source
.braceBadLightIndicatorSet
;
214 braceBadLightIndicator
= source
.braceBadLightIndicator
;
217 ViewStyle::~ViewStyle() {
224 void ViewStyle::Init(size_t stylesSize_
) {
228 AllocStyles(stylesSize_
);
232 indicators
[0].style
= INDIC_SQUIGGLE
;
233 indicators
[0].under
= false;
234 indicators
[0].fore
= ColourDesired(0, 0x7f, 0);
235 indicators
[1].style
= INDIC_TT
;
236 indicators
[1].under
= false;
237 indicators
[1].fore
= ColourDesired(0, 0, 0xff);
238 indicators
[2].style
= INDIC_PLAIN
;
239 indicators
[2].under
= false;
240 indicators
[2].fore
= ColourDesired(0xff, 0, 0);
249 selforeground
.desired
= ColourDesired(0xff, 0, 0);
250 selAdditionalForeground
.desired
= ColourDesired(0xff, 0, 0);
252 selbackground
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
253 selAdditionalBackground
.desired
= ColourDesired(0xd7, 0xd7, 0xd7);
254 selbackground2
.desired
= ColourDesired(0xb0, 0xb0, 0xb0);
255 selAlpha
= SC_ALPHA_NOALPHA
;
256 selAdditionalAlpha
= SC_ALPHA_NOALPHA
;
257 selEOLFilled
= false;
259 foldmarginColourSet
= false;
260 foldmarginColour
.desired
= ColourDesired(0xff, 0, 0);
261 foldmarginHighlightColourSet
= false;
262 foldmarginHighlightColour
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
264 whitespaceForegroundSet
= false;
265 whitespaceForeground
.desired
= ColourDesired(0, 0, 0);
266 whitespaceBackgroundSet
= false;
267 whitespaceBackground
.desired
= ColourDesired(0xff, 0xff, 0xff);
268 selbar
.desired
= Platform::Chrome();
269 selbarlight
.desired
= Platform::ChromeHighlight();
270 styles
[STYLE_LINENUMBER
].fore
.desired
= ColourDesired(0, 0, 0);
271 styles
[STYLE_LINENUMBER
].back
.desired
= Platform::Chrome();
272 caretcolour
.desired
= ColourDesired(0, 0, 0);
273 additionalCaretColour
.desired
= ColourDesired(0x7f, 0x7f, 0x7f);
274 showCaretLineBackground
= false;
275 caretLineBackground
.desired
= ColourDesired(0xff, 0xff, 0);
276 caretLineAlpha
= SC_ALPHA_NOALPHA
;
277 edgecolour
.desired
= ColourDesired(0xc0, 0xc0, 0xc0);
278 edgeState
= EDGE_NONE
;
279 caretStyle
= CARETSTYLE_LINE
;
281 someStylesProtected
= false;
282 someStylesForceCase
= false;
284 hotspotForegroundSet
= false;
285 hotspotForeground
.desired
= ColourDesired(0, 0, 0xff);
286 hotspotBackgroundSet
= false;
287 hotspotBackground
.desired
= ColourDesired(0xff, 0xff, 0xff);
288 hotspotUnderline
= true;
289 hotspotSingleLine
= true;
292 rightMarginWidth
= 1;
293 ms
[0].style
= SC_MARGIN_NUMBER
;
296 ms
[1].style
= SC_MARGIN_SYMBOL
;
298 ms
[1].mask
= ~SC_MASK_FOLDERS
;
299 ms
[2].style
= SC_MARGIN_SYMBOL
;
302 fixedColumnWidth
= leftMarginWidth
;
303 symbolMargin
= false;
304 maskInLine
= 0xffffffff;
305 for (int margin
=0; margin
< margins
; margin
++) {
306 fixedColumnWidth
+= ms
[margin
].width
;
307 symbolMargin
= symbolMargin
|| (ms
[margin
].style
!= SC_MARGIN_NUMBER
);
308 if (ms
[margin
].width
> 0)
309 maskInLine
&= ~ms
[margin
].mask
;
312 viewWhitespace
= wsInvisible
;
314 viewIndentationGuides
= ivNone
;
316 showMarkedLines
= true;
320 marginStyleOffset
= 0;
321 annotationVisible
= ANNOTATION_HIDDEN
;
322 annotationStyleOffset
= 0;
323 braceHighlightIndicatorSet
= false;
324 braceHighlightIndicator
= 0;
325 braceBadLightIndicatorSet
= false;
326 braceBadLightIndicator
= 0;
329 void ViewStyle::RefreshColourPalette(Palette
&pal
, bool want
) {
331 for (i
=0; i
<stylesSize
; i
++) {
332 pal
.WantFind(styles
[i
].fore
, want
);
333 pal
.WantFind(styles
[i
].back
, want
);
335 for (i
=0; i
<(sizeof(indicators
)/sizeof(indicators
[0])); i
++) {
336 pal
.WantFind(indicators
[i
].fore
, want
);
338 for (i
=0; i
<(sizeof(markers
)/sizeof(markers
[0])); i
++) {
339 markers
[i
].RefreshColourPalette(pal
, want
);
341 pal
.WantFind(selforeground
, want
);
342 pal
.WantFind(selAdditionalForeground
, want
);
343 pal
.WantFind(selbackground
, want
);
344 pal
.WantFind(selAdditionalBackground
, want
);
345 pal
.WantFind(selbackground2
, want
);
347 pal
.WantFind(foldmarginColour
, want
);
348 pal
.WantFind(foldmarginHighlightColour
, want
);
350 pal
.WantFind(whitespaceForeground
, want
);
351 pal
.WantFind(whitespaceBackground
, want
);
352 pal
.WantFind(selbar
, want
);
353 pal
.WantFind(selbarlight
, want
);
354 pal
.WantFind(caretcolour
, want
);
355 pal
.WantFind(additionalCaretColour
, want
);
356 pal
.WantFind(caretLineBackground
, want
);
357 pal
.WantFind(edgecolour
, want
);
358 pal
.WantFind(hotspotForeground
, want
);
359 pal
.WantFind(hotspotBackground
, want
);
362 void ViewStyle::CreateFont(const FontSpecification
&fs
) {
364 for (FontRealised
*cur
=frFirst
; cur
; cur
=cur
->frNext
) {
365 if (cur
->EqualTo(fs
))
368 cur
->frNext
= new FontRealised(fs
);
372 frFirst
= new FontRealised(fs
);
376 void ViewStyle::Refresh(Surface
&surface
) {
379 selbar
.desired
= Platform::Chrome();
380 selbarlight
.desired
= Platform::ChromeHighlight();
382 for (unsigned int i
=0; i
<stylesSize
; i
++) {
383 styles
[i
].extraFontFlag
= extraFontFlag
;
386 CreateFont(styles
[STYLE_DEFAULT
]);
387 for (unsigned int j
=0; j
<stylesSize
; j
++) {
388 CreateFont(styles
[j
]);
391 frFirst
->Realise(surface
, zoomLevel
);
393 for (unsigned int k
=0; k
<stylesSize
; k
++) {
394 FontRealised
*fr
= frFirst
->Find(styles
[k
]);
395 styles
[k
].Copy(fr
->font
, *fr
);
399 frFirst
->FindMaxAscentDescent(maxAscent
, maxDescent
);
400 maxAscent
+= extraAscent
;
401 maxDescent
+= extraDescent
;
402 lineHeight
= maxAscent
+ maxDescent
;
404 someStylesProtected
= false;
405 someStylesForceCase
= false;
406 for (unsigned int l
=0; l
<stylesSize
; l
++) {
407 if (styles
[l
].IsProtected()) {
408 someStylesProtected
= true;
410 if (styles
[l
].caseForce
!= Style::caseMixed
) {
411 someStylesForceCase
= true;
415 aveCharWidth
= styles
[STYLE_DEFAULT
].aveCharWidth
;
416 spaceWidth
= styles
[STYLE_DEFAULT
].spaceWidth
;
418 fixedColumnWidth
= leftMarginWidth
;
419 symbolMargin
= false;
420 maskInLine
= 0xffffffff;
421 for (int margin
=0; margin
< margins
; margin
++) {
422 fixedColumnWidth
+= ms
[margin
].width
;
423 symbolMargin
= symbolMargin
|| (ms
[margin
].style
!= SC_MARGIN_NUMBER
);
424 if (ms
[margin
].width
> 0)
425 maskInLine
&= ~ms
[margin
].mask
;
429 void ViewStyle::AllocStyles(size_t sizeNew
) {
430 Style
*stylesNew
= new Style
[sizeNew
];
432 for (; i
<stylesSize
; i
++) {
433 stylesNew
[i
] = styles
[i
];
434 stylesNew
[i
].fontName
= styles
[i
].fontName
;
436 if (stylesSize
> STYLE_DEFAULT
) {
437 for (; i
<sizeNew
; i
++) {
438 if (i
!= STYLE_DEFAULT
) {
439 stylesNew
[i
].ClearTo(styles
[STYLE_DEFAULT
]);
445 stylesSize
= sizeNew
;
448 void ViewStyle::EnsureStyle(size_t index
) {
449 if (index
>= stylesSize
) {
450 size_t sizeNew
= stylesSize
* 2;
451 while (sizeNew
<= index
)
453 AllocStyles(sizeNew
);
457 void ViewStyle::ResetDefaultStyle() {
458 styles
[STYLE_DEFAULT
].Clear(ColourDesired(0,0,0),
459 ColourDesired(0xff,0xff,0xff),
460 Platform::DefaultFontSize(), fontNames
.Save(Platform::DefaultFont()),
462 false, false, false, false, Style::caseMixed
, true, true, false);
465 void ViewStyle::ClearStyles() {
466 // Reset all styles to be like the default style
467 for (unsigned int i
=0; i
<stylesSize
; i
++) {
468 if (i
!= STYLE_DEFAULT
) {
469 styles
[i
].ClearTo(styles
[STYLE_DEFAULT
]);
472 styles
[STYLE_LINENUMBER
].back
.desired
= Platform::Chrome();
474 // Set call tip fore/back to match the values previously set for call tips
475 styles
[STYLE_CALLTIP
].back
.desired
= ColourDesired(0xff, 0xff, 0xff);
476 styles
[STYLE_CALLTIP
].fore
.desired
= ColourDesired(0x80, 0x80, 0x80);
479 void ViewStyle::SetStyleFontName(int styleIndex
, const char *name
) {
480 styles
[styleIndex
].fontName
= fontNames
.Save(name
);
483 bool ViewStyle::ProtectionActive() const {
484 return someStylesProtected
;
487 bool ViewStyle::ValidStyle(size_t styleIndex
) const {
488 return styleIndex
< stylesSize
;