1
// Scintilla source code edit control
2
/** @file LineMarker.cxx
3
** Defines the look of a line marker in the margin .
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"
14
#include "LineMarker.h"
16
void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
17
pal.WantFind(fore, want);
18
pal.WantFind(back, want);
20
pxpm->RefreshColourPalette(pal, want);
24
void LineMarker::SetXPM(const char *textForm) {
26
pxpm = new XPM(textForm);
27
markType = SC_MARK_PIXMAP;
30
void LineMarker::SetXPM(const char * const *linesForm) {
32
pxpm = new XPM(linesForm);
33
markType = SC_MARK_PIXMAP;
36
static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
38
rc.left = centreX - armSize;
39
rc.top = centreY - armSize;
40
rc.right = centreX + armSize + 1;
41
rc.bottom = centreY + armSize + 1;
42
surface->RectangleDraw(rc, back, fore);
45
static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
47
rcCircle.left = centreX - armSize;
48
rcCircle.top = centreY - armSize;
49
rcCircle.right = centreX + armSize + 1;
50
rcCircle.bottom = centreY + armSize + 1;
51
surface->Ellipse(rcCircle, back, fore);
54
static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
55
PRectangle rcV(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1);
56
surface->FillRectangle(rcV, fore);
57
PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
58
surface->FillRectangle(rcH, fore);
61
static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
62
PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
63
surface->FillRectangle(rcH, fore);
66
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
67
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
68
pxpm->Draw(surface, rcWhole);
71
// Restrict most shapes a bit
72
PRectangle rc = rcWhole;
75
int minDim = Platform::Minimum(rc.Width(), rc.Height());
76
minDim--; // Ensure does not go beyond edge
77
int centreX = (rc.right + rc.left) / 2;
78
int centreY = (rc.bottom + rc.top) / 2;
79
int dimOn2 = minDim / 2;
80
int dimOn4 = minDim / 4;
81
int blobSize = dimOn2-1;
82
int armSize = dimOn2-2;
83
if (rc.Width() > (rc.Height() * 2)) {
84
// Wide column is line number so move to left to try to avoid overlapping number
85
centreX = rc.left + dimOn2 + 1;
87
if (markType == SC_MARK_ROUNDRECT) {
88
PRectangle rcRounded = rc;
89
rcRounded.left = rc.left + 1;
90
rcRounded.right = rc.right - 1;
91
surface->RoundedRectangle(rcRounded, fore.allocated, back.allocated);
92
} else if (markType == SC_MARK_CIRCLE) {
94
rcCircle.left = centreX - dimOn2;
95
rcCircle.top = centreY - dimOn2;
96
rcCircle.right = centreX + dimOn2;
97
rcCircle.bottom = centreY + dimOn2;
98
surface->Ellipse(rcCircle, fore.allocated, back.allocated);
99
} else if (markType == SC_MARK_ARROW) {
101
Point(centreX - dimOn4, centreY - dimOn2),
102
Point(centreX - dimOn4, centreY + dimOn2),
103
Point(centreX + dimOn2 - dimOn4, centreY),
105
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
106
fore.allocated, back.allocated);
108
} else if (markType == SC_MARK_ARROWDOWN) {
110
Point(centreX - dimOn2, centreY - dimOn4),
111
Point(centreX + dimOn2, centreY - dimOn4),
112
Point(centreX, centreY + dimOn2 - dimOn4),
114
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
115
fore.allocated, back.allocated);
117
} else if (markType == SC_MARK_PLUS) {
119
Point(centreX - armSize, centreY - 1),
120
Point(centreX - 1, centreY - 1),
121
Point(centreX - 1, centreY - armSize),
122
Point(centreX + 1, centreY - armSize),
123
Point(centreX + 1, centreY - 1),
124
Point(centreX + armSize, centreY -1),
125
Point(centreX + armSize, centreY +1),
126
Point(centreX + 1, centreY + 1),
127
Point(centreX + 1, centreY + armSize),
128
Point(centreX - 1, centreY + armSize),
129
Point(centreX - 1, centreY + 1),
130
Point(centreX - armSize, centreY + 1),
132
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
133
fore.allocated, back.allocated);
135
} else if (markType == SC_MARK_MINUS) {
137
Point(centreX - armSize, centreY - 1),
138
Point(centreX + armSize, centreY -1),
139
Point(centreX + armSize, centreY +1),
140
Point(centreX - armSize, centreY + 1),
142
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
143
fore.allocated, back.allocated);
145
} else if (markType == SC_MARK_SMALLRECT) {
147
rcSmall.left = rc.left + 1;
148
rcSmall.top = rc.top + 2;
149
rcSmall.right = rc.right - 1;
150
rcSmall.bottom = rc.bottom - 2;
151
surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
153
} else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
154
// An invisible marker so don't draw anything
156
} else if (markType == SC_MARK_VLINE) {
157
surface->PenColour(back.allocated);
158
surface->MoveTo(centreX, rcWhole.top);
159
surface->LineTo(centreX, rcWhole.bottom);
161
} else if (markType == SC_MARK_LCORNER) {
162
surface->PenColour(back.allocated);
163
surface->MoveTo(centreX, rcWhole.top);
164
surface->LineTo(centreX, rc.top + dimOn2);
165
surface->LineTo(rc.right - 2, rc.top + dimOn2);
167
} else if (markType == SC_MARK_TCORNER) {
168
surface->PenColour(back.allocated);
169
surface->MoveTo(centreX, rcWhole.top);
170
surface->LineTo(centreX, rcWhole.bottom);
171
surface->MoveTo(centreX, rc.top + dimOn2);
172
surface->LineTo(rc.right - 2, rc.top + dimOn2);
174
} else if (markType == SC_MARK_LCORNERCURVE) {
175
surface->PenColour(back.allocated);
176
surface->MoveTo(centreX, rcWhole.top);
177
surface->LineTo(centreX, rc.top + dimOn2-3);
178
surface->LineTo(centreX+3, rc.top + dimOn2);
179
surface->LineTo(rc.right - 1, rc.top + dimOn2);
181
} else if (markType == SC_MARK_TCORNERCURVE) {
182
surface->PenColour(back.allocated);
183
surface->MoveTo(centreX, rcWhole.top);
184
surface->LineTo(centreX, rcWhole.bottom);
186
surface->MoveTo(centreX, rc.top + dimOn2-3);
187
surface->LineTo(centreX+3, rc.top + dimOn2);
188
surface->LineTo(rc.right - 1, rc.top + dimOn2);
190
} else if (markType == SC_MARK_BOXPLUS) {
191
surface->PenColour(back.allocated);
192
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
193
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
195
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
196
surface->PenColour(back.allocated);
197
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
198
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
200
surface->MoveTo(centreX, centreY + blobSize);
201
surface->LineTo(centreX, rcWhole.bottom);
203
surface->MoveTo(centreX, rcWhole.top);
204
surface->LineTo(centreX, centreY - blobSize);
206
} else if (markType == SC_MARK_BOXMINUS) {
207
surface->PenColour(back.allocated);
208
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
209
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
211
surface->MoveTo(centreX, centreY + blobSize);
212
surface->LineTo(centreX, rcWhole.bottom);
214
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
215
surface->PenColour(back.allocated);
216
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
217
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
219
surface->MoveTo(centreX, centreY + blobSize);
220
surface->LineTo(centreX, rcWhole.bottom);
222
surface->MoveTo(centreX, rcWhole.top);
223
surface->LineTo(centreX, centreY - blobSize);
225
} else if (markType == SC_MARK_CIRCLEPLUS) {
226
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
227
surface->PenColour(back.allocated);
228
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
230
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
231
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
232
surface->PenColour(back.allocated);
233
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
235
surface->MoveTo(centreX, centreY + blobSize);
236
surface->LineTo(centreX, rcWhole.bottom);
238
surface->MoveTo(centreX, rcWhole.top);
239
surface->LineTo(centreX, centreY - blobSize);
241
} else if (markType == SC_MARK_CIRCLEMINUS) {
242
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
243
surface->PenColour(back.allocated);
244
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
246
surface->MoveTo(centreX, centreY + blobSize);
247
surface->LineTo(centreX, rcWhole.bottom);
249
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
250
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
251
surface->PenColour(back.allocated);
252
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
254
surface->MoveTo(centreX, centreY + blobSize);
255
surface->LineTo(centreX, rcWhole.bottom);
257
surface->MoveTo(centreX, rcWhole.top);
258
surface->LineTo(centreX, centreY - blobSize);
260
} else if (markType >= SC_MARK_CHARACTER) {
262
character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
263
int width = surface->WidthText(fontForCharacter, character, 1);
264
rc.left += (rc.Width() - width) / 2;
265
rc.right = rc.left + width;
266
surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
267
character, 1, fore.allocated, back.allocated);
269
} else if (markType == SC_MARK_DOTDOTDOT) {
270
int right = centreX - 6;
271
for (int b=0; b<3; b++) {
272
PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
273
surface->FillRectangle(rcBlob, fore.allocated);
276
} else if (markType == SC_MARK_ARROWS) {
277
surface->PenColour(fore.allocated);
278
int right = centreX - 2;
279
for (int b=0; b<3; b++) {
280
surface->MoveTo(right - 4, centreY - 4);
281
surface->LineTo(right, centreY);
282
surface->LineTo(right - 5, centreY + 5);
285
} else if (markType == SC_MARK_SHORTARROW) {
287
Point(centreX, centreY + dimOn2),
288
Point(centreX + dimOn2, centreY),
289
Point(centreX, centreY - dimOn2),
290
Point(centreX, centreY - dimOn4),
291
Point(centreX - dimOn4, centreY - dimOn4),
292
Point(centreX - dimOn4, centreY + dimOn4),
293
Point(centreX, centreY + dimOn4),
294
Point(centreX, centreY + dimOn2),
296
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
297
fore.allocated, back.allocated);
298
} else { // SC_MARK_FULLRECT
299
surface->FillRectangle(rcWhole, back.allocated);