29
30
using namespace Scintilla;
32
MarginStyle::MarginStyle() :
33
style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
33
MarginStyle::MarginStyle(int style_, int width_, int mask_) :
34
style(style_), width(width_), mask(mask_), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
36
37
// A list of the fontnames - avoids wasting space in each style
44
45
void FontNames::Clear() {
45
for (std::vector<char *>::const_iterator it=names.begin(); it != names.end(); ++it) {
51
49
const char *FontNames::Save(const char *name) {
55
for (std::vector<char *>::const_iterator it=names.begin(); it != names.end(); ++it) {
56
if (strcmp(*it, name) == 0) {
53
for (const UniqueString &nm : names) {
54
if (strcmp(nm.get(), name) == 0) {
60
const size_t lenName = strlen(name) + 1;
61
char *nameSave = new char[lenName];
62
memcpy(nameSave, name, lenName);
63
names.push_back(nameSave);
59
names.push_back(UniqueStringCopy(name));
60
return names.back().get();
67
63
FontRealised::FontRealised() {
84
80
ascent = static_cast<unsigned int>(surface.Ascent(font));
85
81
descent = static_cast<unsigned int>(surface.Descent(font));
82
capitalHeight = surface.Ascent(font) - surface.InternalLeading(font);
86
83
aveCharWidth = surface.AverageCharWidth(font);
87
84
spaceWidth = surface.WidthChar(font, ' ');
90
ViewStyle::ViewStyle() {
87
ViewStyle::ViewStyle() : markers(MARKER_MAX + 1), indicators(INDIC_MAX + 1) {
94
ViewStyle::ViewStyle(const ViewStyle &source) {
91
// Copy constructor only called when printing copies the screen ViewStyle so it can be
92
// modified for printing styles.
93
ViewStyle::ViewStyle(const ViewStyle &source) : markers(MARKER_MAX + 1), indicators(INDIC_MAX + 1) {
95
94
Init(source.styles.size());
96
for (unsigned int sty=0; sty<source.styles.size(); sty++) {
97
styles[sty] = source.styles[sty];
98
// Can't just copy fontname as its lifetime is relative to its owning ViewStyle
95
styles = source.styles;
96
for (size_t sty=0; sty<source.styles.size(); sty++) {
97
// Can't just copy fontName as its lifetime is relative to its owning ViewStyle
99
98
styles[sty].fontName = fontNames.Save(source.styles[sty].fontName);
101
100
nextExtendedStyle = source.nextExtendedStyle;
102
for (int mrk=0; mrk<=MARKER_MAX; mrk++) {
103
markers[mrk] = source.markers[mrk];
101
markers = source.markers;
105
102
CalcLargestMarkerHeight();
106
indicatorsDynamic = 0;
107
indicatorsSetFore = 0;
108
for (int ind=0; ind<=INDIC_MAX; ind++) {
109
indicators[ind] = source.indicators[ind];
110
if (indicators[ind].IsDynamic())
112
if (indicators[ind].OverridesTextFore())
104
indicators = source.indicators;
106
indicatorsDynamic = source.indicatorsDynamic;
107
indicatorsSetFore = source.indicatorsSetFore;
116
109
selColours = source.selColours;
117
110
selAdditionalForeground = source.selAdditionalForeground;
135
128
selbarlight = source.selbarlight;
136
129
caretcolour = source.caretcolour;
137
130
additionalCaretColour = source.additionalCaretColour;
131
caretLineFrame = source.caretLineFrame;
138
132
showCaretLineBackground = source.showCaretLineBackground;
139
133
alwaysShowCaretLineBackground = source.alwaysShowCaretLineBackground;
140
134
caretLineBackground = source.caretLineBackground;
195
186
fixedColumnWidth = marginInside ? leftMarginWidth : 0;
196
187
maskInLine = 0xffffffff;
197
188
int maskDefinedMarkers = 0;
198
for (size_t margin = 0; margin < ms.size(); margin++) {
199
fixedColumnWidth += ms[margin].width;
200
if (ms[margin].width > 0)
201
maskInLine &= ~ms[margin].mask;
202
maskDefinedMarkers |= ms[margin].mask;
189
for (const MarginStyle &m : ms) {
190
fixedColumnWidth += m.width;
192
maskInLine &= ~m.mask;
193
maskDefinedMarkers |= m.mask;
204
195
maskDrawInText = 0;
205
196
for (int markBit = 0; markBit < 32; markBit++) {
231
222
indicators[2] = Indicator(INDIC_PLAIN, ColourDesired(0xff, 0, 0));
233
224
technology = SC_TECHNOLOGY_DEFAULT;
234
indicatorsDynamic = 0;
235
indicatorsSetFore = 0;
225
indicatorsDynamic = false;
226
indicatorsSetFore = false;
263
254
styles[STYLE_LINENUMBER].back = Platform::Chrome();
264
255
caretcolour = ColourDesired(0, 0, 0);
265
256
additionalCaretColour = ColourDesired(0x7f, 0x7f, 0x7f);
266
258
showCaretLineBackground = false;
267
259
alwaysShowCaretLineBackground = false;
268
260
caretLineBackground = ColourDesired(0xff, 0xff, 0);
280
272
leftMarginWidth = 1;
281
273
rightMarginWidth = 1;
282
274
ms.resize(SC_MAX_MARGIN + 1);
283
ms[0].style = SC_MARGIN_NUMBER;
286
ms[1].style = SC_MARGIN_SYMBOL;
288
ms[1].mask = ~SC_MASK_FOLDERS;
289
ms[2].style = SC_MARGIN_SYMBOL;
275
ms[0] = MarginStyle(SC_MARGIN_NUMBER);
276
ms[1] = MarginStyle(SC_MARGIN_SYMBOL, 16, ~SC_MASK_FOLDERS);
277
ms[2] = MarginStyle(SC_MARGIN_SYMBOL);
292
278
marginInside = true;
293
279
CalculateMarginWidthAndMask();
294
280
textStart = marginInside ? fixedColumnWidth : leftMarginWidth;
326
312
void ViewStyle::Refresh(Surface &surface, int tabInChars) {
327
for (FontMap::iterator it = fonts.begin(); it != fonts.end(); ++it) {
332
315
selbar = Platform::Chrome();
333
316
selbarlight = Platform::ChromeHighlight();
335
for (unsigned int i=0; i<styles.size(); i++) {
336
styles[i].extraFontFlag = extraFontFlag;
318
// Apply the extra font flag which controls text drawing quality to each style.
319
for (Style &style : styles) {
320
style.extraFontFlag = extraFontFlag;
323
// Create a FontRealised object for each unique font in the styles.
339
324
CreateAndAddFont(styles[STYLE_DEFAULT]);
340
for (unsigned int j=0; j<styles.size(); j++) {
341
CreateAndAddFont(styles[j]);
344
for (FontMap::iterator it = fonts.begin(); it != fonts.end(); ++it) {
345
it->second->Realise(surface, zoomLevel, technology, it->first);
348
for (unsigned int k=0; k<styles.size(); k++) {
349
FontRealised *fr = Find(styles[k]);
350
styles[k].Copy(fr->font, *fr);
352
indicatorsDynamic = 0;
353
indicatorsSetFore = 0;
354
for (int ind = 0; ind <= INDIC_MAX; ind++) {
355
if (indicators[ind].IsDynamic())
357
if (indicators[ind].OverridesTextFore())
325
for (const Style &style : styles) {
326
CreateAndAddFont(style);
329
// Ask platform to allocate each unique font.
330
for (std::pair<const FontSpecification, std::unique_ptr<FontRealised>> &font : fonts) {
331
font.second->Realise(surface, zoomLevel, technology, font.first);
334
// Set the platform font handle and measurements for each style.
335
for (Style &style : styles) {
336
FontRealised *fr = Find(style);
337
style.Copy(fr->font, *fr);
340
indicatorsDynamic = std::any_of(indicators.cbegin(), indicators.cend(),
341
[](const Indicator &indicator) { return indicator.IsDynamic(); });
343
indicatorsSetFore = std::any_of(indicators.cbegin(), indicators.cend(),
344
[](const Indicator &indicator) { return indicator.OverridesTextFore(); });
362
348
FindMaxAscentDescent();
369
355
if (lineOverlap > lineHeight)
370
356
lineOverlap = lineHeight;
372
someStylesProtected = false;
373
someStylesForceCase = false;
374
for (unsigned int l=0; l<styles.size(); l++) {
375
if (styles[l].IsProtected()) {
376
someStylesProtected = true;
378
if (styles[l].caseForce != Style::caseMixed) {
379
someStylesForceCase = true;
358
someStylesProtected = std::any_of(styles.cbegin(), styles.cend(),
359
[](const Style &style) { return style.IsProtected(); });
361
someStylesForceCase = std::any_of(styles.cbegin(), styles.cend(),
362
[](const Style &style) { return style.caseForce != Style::caseMixed; });
383
364
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
384
365
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
465
446
void ViewStyle::CalcLargestMarkerHeight() {
466
447
largestMarkerHeight = 0;
467
for (int m = 0; m <= MARKER_MAX; ++m) {
468
switch (markers[m].markType) {
448
for (const LineMarker &marker : markers) {
449
switch (marker.markType) {
469
450
case SC_MARK_PIXMAP:
470
if (markers[m].pxpm && markers[m].pxpm->GetHeight() > largestMarkerHeight)
471
largestMarkerHeight = markers[m].pxpm->GetHeight();
451
if (marker.pxpm && marker.pxpm->GetHeight() > largestMarkerHeight)
452
largestMarkerHeight = marker.pxpm->GetHeight();
473
454
case SC_MARK_RGBAIMAGE:
474
if (markers[m].image && markers[m].image->GetHeight() > largestMarkerHeight)
475
largestMarkerHeight = markers[m].image->GetHeight();
455
if (marker.image && marker.image->GetHeight() > largestMarkerHeight)
456
largestMarkerHeight = marker.image->GetHeight();
462
int ViewStyle::GetFrameWidth() const {
463
return Platform::Clamp(caretLineFrame, 1, lineHeight / 3);
466
bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const {
467
return caretLineFrame && (caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground &&
468
(caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret;
481
471
// See if something overrides the line background color: Either if caret is on the line
482
472
// and background color is set for that, or if a marker is defined that forces its background
483
473
// color onto the line, or if a marker is defined but has no selection margin in which to
486
476
// the color for the highest numbered one is used.
487
477
ColourOptional ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const {
488
478
ColourOptional background;
489
if ((caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground && (caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret) {
479
if (!caretLineFrame && (caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground &&
480
(caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret) {
490
481
background = ColourOptional(caretLineBackground, true);
492
483
if (!background.isSet && marksOfLine) {
552
543
wrapStateWanted = eWrapNone;
555
bool changed = wrapState != wrapStateWanted;
546
const bool changed = wrapState != wrapStateWanted;
556
547
wrapState = wrapStateWanted;
560
551
bool ViewStyle::SetWrapVisualFlags(int wrapVisualFlags_) {
561
bool changed = wrapVisualFlags != wrapVisualFlags_;
552
const bool changed = wrapVisualFlags != wrapVisualFlags_;
562
553
wrapVisualFlags = wrapVisualFlags_;
566
557
bool ViewStyle::SetWrapVisualFlagsLocation(int wrapVisualFlagsLocation_) {
567
bool changed = wrapVisualFlagsLocation != wrapVisualFlagsLocation_;
558
const bool changed = wrapVisualFlagsLocation != wrapVisualFlagsLocation_;
568
559
wrapVisualFlagsLocation = wrapVisualFlagsLocation_;
572
563
bool ViewStyle::SetWrapVisualStartIndent(int wrapVisualStartIndent_) {
573
bool changed = wrapVisualStartIndent != wrapVisualStartIndent_;
564
const bool changed = wrapVisualStartIndent != wrapVisualStartIndent_;
574
565
wrapVisualStartIndent = wrapVisualStartIndent_;
578
569
bool ViewStyle::SetWrapIndentMode(int wrapIndentMode_) {
579
bool changed = wrapIndentMode != wrapIndentMode_;
570
const bool changed = wrapIndentMode != wrapIndentMode_;
580
571
wrapIndentMode = wrapIndentMode_;
597
588
if (fs.fontName) {
598
589
FontMap::iterator it = fonts.find(fs);
599
590
if (it == fonts.end()) {
600
fonts[fs] = new FontRealised();
591
fonts[fs] = std::unique_ptr<FontRealised>(new FontRealised());
605
596
FontRealised *ViewStyle::Find(const FontSpecification &fs) {
606
597
if (!fs.fontName) // Invalid specification so return arbitrary object
607
return fonts.begin()->second;
598
return fonts.begin()->second.get();
608
599
FontMap::iterator it = fonts.find(fs);
609
600
if (it != fonts.end()) {
610
601
// Should always reach here since map was just set for all styles
602
return it->second.get();
616
607
void ViewStyle::FindMaxAscentDescent() {
617
for (FontMap::const_iterator it = fonts.begin(); it != fonts.end(); ++it) {
608
for (FontMap::const_iterator it = fonts.cbegin(); it != fonts.cend(); ++it) {
618
609
if (maxAscent < it->second->ascent)
619
610
maxAscent = it->second->ascent;
620
611
if (maxDescent < it->second->descent)