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
, 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
;
95 float deviceHeight
= surface
.DeviceHeightFont(sizeZoomed
);
96 FontParameters
fp(fontName
, deviceHeight
/ SC_FONT_SIZE_MULTIPLIER
, weight
, italic
, extraFontFlag
, technology
, characterSet
);
99 ascent
= surface
.Ascent(font
);
100 descent
= surface
.Descent(font
);
101 aveCharWidth
= surface
.AverageCharWidth(font
);
102 spaceWidth
= surface
.WidthChar(font
, ' ');
104 frNext
->Realise(surface
, zoomLevel
, technology
);
108 FontRealised
*FontRealised::Find(const FontSpecification
&fs
) {
111 FontRealised
*fr
= this;
120 void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent
, unsigned int &maxDescent
) {
121 FontRealised
*fr
= this;
123 if (maxAscent
< fr
->ascent
)
124 maxAscent
= fr
->ascent
;
125 if (maxDescent
< fr
->descent
)
126 maxDescent
= fr
->descent
;
131 ViewStyle::ViewStyle() {
135 ViewStyle::ViewStyle(const ViewStyle
&source
) {
137 Init(source
.stylesSize
);
138 for (unsigned int sty
=0; sty
<source
.stylesSize
; sty
++) {
139 styles
[sty
] = source
.styles
[sty
];
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
);
143 for (int mrk
=0; mrk
<=MARKER_MAX
; mrk
++) {
144 markers
[mrk
] = source
.markers
[mrk
];
146 CalcLargestMarkerHeight();
147 for (int ind
=0; ind
<=INDIC_MAX
; ind
++) {
148 indicators
[ind
] = source
.indicators
[ind
];
151 selforeset
= source
.selforeset
;
152 selforeground
= source
.selforeground
;
153 selAdditionalForeground
= source
.selAdditionalForeground
;
154 selbackset
= source
.selbackset
;
155 selbackground
= source
.selbackground
;
156 selAdditionalBackground
= source
.selAdditionalBackground
;
157 selbackground2
= source
.selbackground2
;
158 selAlpha
= source
.selAlpha
;
159 selAdditionalAlpha
= source
.selAdditionalAlpha
;
160 selEOLFilled
= source
.selEOLFilled
;
162 foldmarginColourSet
= source
.foldmarginColourSet
;
163 foldmarginColour
= source
.foldmarginColour
;
164 foldmarginHighlightColourSet
= source
.foldmarginHighlightColourSet
;
165 foldmarginHighlightColour
= source
.foldmarginHighlightColour
;
167 hotspotForegroundSet
= source
.hotspotForegroundSet
;
168 hotspotForeground
= source
.hotspotForeground
;
169 hotspotBackgroundSet
= source
.hotspotBackgroundSet
;
170 hotspotBackground
= source
.hotspotBackground
;
171 hotspotUnderline
= source
.hotspotUnderline
;
172 hotspotSingleLine
= source
.hotspotSingleLine
;
174 whitespaceForegroundSet
= source
.whitespaceForegroundSet
;
175 whitespaceForeground
= source
.whitespaceForeground
;
176 whitespaceBackgroundSet
= source
.whitespaceBackgroundSet
;
177 whitespaceBackground
= source
.whitespaceBackground
;
178 selbar
= source
.selbar
;
179 selbarlight
= source
.selbarlight
;
180 caretcolour
= source
.caretcolour
;
181 additionalCaretColour
= source
.additionalCaretColour
;
182 showCaretLineBackground
= source
.showCaretLineBackground
;
183 alwaysShowCaretLineBackground
= source
.alwaysShowCaretLineBackground
;
184 caretLineBackground
= source
.caretLineBackground
;
185 caretLineAlpha
= source
.caretLineAlpha
;
186 edgecolour
= source
.edgecolour
;
187 edgeState
= source
.edgeState
;
188 caretStyle
= source
.caretStyle
;
189 caretWidth
= source
.caretWidth
;
190 someStylesProtected
= false;
191 someStylesForceCase
= false;
192 leftMarginWidth
= source
.leftMarginWidth
;
193 rightMarginWidth
= source
.rightMarginWidth
;
194 for (int i
=0; i
< margins
; i
++) {
195 ms
[i
] = source
.ms
[i
];
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 extraFontFlag
= source
.extraFontFlag
;
205 extraAscent
= source
.extraAscent
;
206 extraDescent
= source
.extraDescent
;
207 marginStyleOffset
= source
.marginStyleOffset
;
208 annotationVisible
= source
.annotationVisible
;
209 annotationStyleOffset
= source
.annotationStyleOffset
;
210 braceHighlightIndicatorSet
= source
.braceHighlightIndicatorSet
;
211 braceHighlightIndicator
= source
.braceHighlightIndicator
;
212 braceBadLightIndicatorSet
= source
.braceBadLightIndicatorSet
;
213 braceBadLightIndicator
= source
.braceBadLightIndicator
;
216 ViewStyle::~ViewStyle() {
223 void ViewStyle::Init(size_t stylesSize_
) {
227 AllocStyles(stylesSize_
);
231 // There are no image markers by default, so no need for calling CalcLargestMarkerHeight()
232 largestMarkerHeight
= 0;
234 indicators
[0].style
= INDIC_SQUIGGLE
;
235 indicators
[0].under
= false;
236 indicators
[0].fore
= ColourDesired(0, 0x7f, 0);
237 indicators
[1].style
= INDIC_TT
;
238 indicators
[1].under
= false;
239 indicators
[1].fore
= ColourDesired(0, 0, 0xff);
240 indicators
[2].style
= INDIC_PLAIN
;
241 indicators
[2].under
= false;
242 indicators
[2].fore
= ColourDesired(0xff, 0, 0);
244 technology
= SC_TECHNOLOGY_DEFAULT
;
252 selforeground
= ColourDesired(0xff, 0, 0);
253 selAdditionalForeground
= ColourDesired(0xff, 0, 0);
255 selbackground
= ColourDesired(0xc0, 0xc0, 0xc0);
256 selAdditionalBackground
= ColourDesired(0xd7, 0xd7, 0xd7);
257 selbackground2
= ColourDesired(0xb0, 0xb0, 0xb0);
258 selAlpha
= SC_ALPHA_NOALPHA
;
259 selAdditionalAlpha
= SC_ALPHA_NOALPHA
;
260 selEOLFilled
= false;
262 foldmarginColourSet
= false;
263 foldmarginColour
= ColourDesired(0xff, 0, 0);
264 foldmarginHighlightColourSet
= false;
265 foldmarginHighlightColour
= ColourDesired(0xc0, 0xc0, 0xc0);
267 whitespaceForegroundSet
= false;
268 whitespaceForeground
= ColourDesired(0, 0, 0);
269 whitespaceBackgroundSet
= false;
270 whitespaceBackground
= ColourDesired(0xff, 0xff, 0xff);
271 selbar
= Platform::Chrome();
272 selbarlight
= Platform::ChromeHighlight();
273 styles
[STYLE_LINENUMBER
].fore
= ColourDesired(0, 0, 0);
274 styles
[STYLE_LINENUMBER
].back
= Platform::Chrome();
275 caretcolour
= ColourDesired(0, 0, 0);
276 additionalCaretColour
= ColourDesired(0x7f, 0x7f, 0x7f);
277 showCaretLineBackground
= false;
278 alwaysShowCaretLineBackground
= false;
279 caretLineBackground
= ColourDesired(0xff, 0xff, 0);
280 caretLineAlpha
= SC_ALPHA_NOALPHA
;
281 edgecolour
= ColourDesired(0xc0, 0xc0, 0xc0);
282 edgeState
= EDGE_NONE
;
283 caretStyle
= CARETSTYLE_LINE
;
285 someStylesProtected
= false;
286 someStylesForceCase
= false;
288 hotspotForegroundSet
= false;
289 hotspotForeground
= ColourDesired(0, 0, 0xff);
290 hotspotBackgroundSet
= false;
291 hotspotBackground
= ColourDesired(0xff, 0xff, 0xff);
292 hotspotUnderline
= true;
293 hotspotSingleLine
= true;
296 rightMarginWidth
= 1;
297 ms
[0].style
= SC_MARGIN_NUMBER
;
300 ms
[1].style
= SC_MARGIN_SYMBOL
;
302 ms
[1].mask
= ~SC_MASK_FOLDERS
;
303 ms
[2].style
= SC_MARGIN_SYMBOL
;
306 fixedColumnWidth
= leftMarginWidth
;
307 maskInLine
= 0xffffffff;
308 for (int margin
=0; margin
< margins
; margin
++) {
309 fixedColumnWidth
+= ms
[margin
].width
;
310 if (ms
[margin
].width
> 0)
311 maskInLine
&= ~ms
[margin
].mask
;
314 viewWhitespace
= wsInvisible
;
316 viewIndentationGuides
= ivNone
;
321 marginStyleOffset
= 0;
322 annotationVisible
= ANNOTATION_HIDDEN
;
323 annotationStyleOffset
= 0;
324 braceHighlightIndicatorSet
= false;
325 braceHighlightIndicator
= 0;
326 braceBadLightIndicatorSet
= false;
327 braceBadLightIndicator
= 0;
330 void ViewStyle::CreateFont(const FontSpecification
&fs
) {
332 for (FontRealised
*cur
=frFirst
; cur
; cur
=cur
->frNext
) {
333 if (cur
->EqualTo(fs
))
336 cur
->frNext
= new FontRealised(fs
);
340 frFirst
= new FontRealised(fs
);
344 void ViewStyle::Refresh(Surface
&surface
) {
347 selbar
= Platform::Chrome();
348 selbarlight
= Platform::ChromeHighlight();
350 for (unsigned int i
=0; i
<stylesSize
; i
++) {
351 styles
[i
].extraFontFlag
= extraFontFlag
;
354 CreateFont(styles
[STYLE_DEFAULT
]);
355 for (unsigned int j
=0; j
<stylesSize
; j
++) {
356 CreateFont(styles
[j
]);
359 frFirst
->Realise(surface
, zoomLevel
, technology
);
361 for (unsigned int k
=0; k
<stylesSize
; k
++) {
362 FontRealised
*fr
= frFirst
->Find(styles
[k
]);
363 styles
[k
].Copy(fr
->font
, *fr
);
367 frFirst
->FindMaxAscentDescent(maxAscent
, maxDescent
);
368 maxAscent
+= extraAscent
;
369 maxDescent
+= extraDescent
;
370 lineHeight
= maxAscent
+ maxDescent
;
372 someStylesProtected
= false;
373 someStylesForceCase
= false;
374 for (unsigned int l
=0; l
<stylesSize
; l
++) {
375 if (styles
[l
].IsProtected()) {
376 someStylesProtected
= true;
378 if (styles
[l
].caseForce
!= Style::caseMixed
) {
379 someStylesForceCase
= true;
383 aveCharWidth
= styles
[STYLE_DEFAULT
].aveCharWidth
;
384 spaceWidth
= styles
[STYLE_DEFAULT
].spaceWidth
;
386 fixedColumnWidth
= leftMarginWidth
;
387 maskInLine
= 0xffffffff;
388 for (int margin
=0; margin
< margins
; margin
++) {
389 fixedColumnWidth
+= ms
[margin
].width
;
390 if (ms
[margin
].width
> 0)
391 maskInLine
&= ~ms
[margin
].mask
;
395 void ViewStyle::AllocStyles(size_t sizeNew
) {
396 Style
*stylesNew
= new Style
[sizeNew
];
398 for (; i
<stylesSize
; i
++) {
399 stylesNew
[i
] = styles
[i
];
400 stylesNew
[i
].fontName
= styles
[i
].fontName
;
402 if (stylesSize
> STYLE_DEFAULT
) {
403 for (; i
<sizeNew
; i
++) {
404 if (i
!= STYLE_DEFAULT
) {
405 stylesNew
[i
].ClearTo(styles
[STYLE_DEFAULT
]);
411 stylesSize
= sizeNew
;
414 void ViewStyle::EnsureStyle(size_t index
) {
415 if (index
>= stylesSize
) {
416 size_t sizeNew
= stylesSize
* 2;
417 while (sizeNew
<= index
)
419 AllocStyles(sizeNew
);
423 void ViewStyle::ResetDefaultStyle() {
424 styles
[STYLE_DEFAULT
].Clear(ColourDesired(0,0,0),
425 ColourDesired(0xff,0xff,0xff),
426 Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER
, fontNames
.Save(Platform::DefaultFont()),
428 SC_WEIGHT_NORMAL
, false, false, false, Style::caseMixed
, true, true, false);
431 void ViewStyle::ClearStyles() {
432 // Reset all styles to be like the default style
433 for (unsigned int i
=0; i
<stylesSize
; i
++) {
434 if (i
!= STYLE_DEFAULT
) {
435 styles
[i
].ClearTo(styles
[STYLE_DEFAULT
]);
438 styles
[STYLE_LINENUMBER
].back
= Platform::Chrome();
440 // Set call tip fore/back to match the values previously set for call tips
441 styles
[STYLE_CALLTIP
].back
= ColourDesired(0xff, 0xff, 0xff);
442 styles
[STYLE_CALLTIP
].fore
= ColourDesired(0x80, 0x80, 0x80);
445 void ViewStyle::SetStyleFontName(int styleIndex
, const char *name
) {
446 styles
[styleIndex
].fontName
= fontNames
.Save(name
);
449 bool ViewStyle::ProtectionActive() const {
450 return someStylesProtected
;
453 bool ViewStyle::ValidStyle(size_t styleIndex
) const {
454 return styleIndex
< stylesSize
;
457 void ViewStyle::CalcLargestMarkerHeight() {
458 largestMarkerHeight
= 0;
459 for (int m
= 0; m
<= MARKER_MAX
; ++m
) {
460 switch (markers
[m
].markType
) {
462 if (markers
[m
].pxpm
->GetHeight() > largestMarkerHeight
)
463 largestMarkerHeight
= markers
[m
].pxpm
->GetHeight();
465 case SC_MARK_RGBAIMAGE
:
466 if (markers
[m
].image
->GetHeight() > largestMarkerHeight
)
467 largestMarkerHeight
= markers
[m
].image
->GetHeight();