1 // Scintilla source code edit control
2 /** @file LineMarker.cxx
3 ** Defines the look of a line marker in the margin .
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
10 #include "Scintilla.h"
11 #include "LineMarker.h"
13 static void DrawBox(Surface
*surface
, int centreX
, int centreY
, int armSize
, ColourAllocated fore
, ColourAllocated back
) {
15 rc
.left
= centreX
- armSize
;
16 rc
.top
= centreY
- armSize
;
17 rc
.right
= centreX
+ armSize
+ 1;
18 rc
.bottom
= centreY
+ armSize
+ 1;
19 surface
->RectangleDraw(rc
, back
, fore
);
22 static void DrawCircle(Surface
*surface
, int centreX
, int centreY
, int armSize
, ColourAllocated fore
, ColourAllocated back
) {
24 rcCircle
.left
= centreX
- armSize
;
25 rcCircle
.top
= centreY
- armSize
;
26 rcCircle
.right
= centreX
+ armSize
+ 1;
27 rcCircle
.bottom
= centreY
+ armSize
+ 1;
28 surface
->Ellipse(rcCircle
, back
, fore
);
31 static void DrawPlus(Surface
*surface
, int centreX
, int centreY
, int armSize
, ColourAllocated fore
) {
32 PRectangle
rcV(centreX
, centreY
- armSize
+ 2, centreX
+ 1, centreY
+ armSize
- 2 + 1);
33 surface
->FillRectangle(rcV
, fore
);
34 PRectangle
rcH(centreX
- armSize
+ 2, centreY
, centreX
+ armSize
- 2 + 1, centreY
+1);
35 surface
->FillRectangle(rcH
, fore
);
38 static void DrawMinus(Surface
*surface
, int centreX
, int centreY
, int armSize
, ColourAllocated fore
) {
39 PRectangle
rcH(centreX
- armSize
+ 2, centreY
, centreX
+ armSize
- 2 + 1, centreY
+1);
40 surface
->FillRectangle(rcH
, fore
);
43 void LineMarker::Draw(Surface
*surface
, PRectangle
&rcWhole
, Font
&fontForCharacter
) {
44 // Restrict most shapes a bit
45 PRectangle rc
= rcWhole
;
48 int minDim
= Platform::Minimum(rc
.Width(), rc
.Height());
49 minDim
--; // Ensure does not go beyond edge
50 int centreX
= (rc
.right
+ rc
.left
) / 2;
51 int centreY
= (rc
.bottom
+ rc
.top
) / 2;
52 int dimOn2
= minDim
/ 2;
53 int dimOn4
= minDim
/ 4;
54 int blobSize
= dimOn2
-1;
55 int armSize
= dimOn2
-2;
56 if (rc
.Width() > (rc
.Height() * 2)) {
57 // Wide column is line number so move to left to try to avoid overlapping number
58 centreX
= rc
.left
+ dimOn2
+ 1;
60 if (markType
== SC_MARK_ROUNDRECT
) {
61 PRectangle rcRounded
= rc
;
62 rcRounded
.left
= rc
.left
+ 1;
63 rcRounded
.right
= rc
.right
- 1;
64 surface
->RoundedRectangle(rcRounded
, fore
.allocated
, back
.allocated
);
65 } else if (markType
== SC_MARK_CIRCLE
) {
67 rcCircle
.left
= centreX
- dimOn2
;
68 rcCircle
.top
= centreY
- dimOn2
;
69 rcCircle
.right
= centreX
+ dimOn2
;
70 rcCircle
.bottom
= centreY
+ dimOn2
;
71 surface
->Ellipse(rcCircle
, fore
.allocated
, back
.allocated
);
72 } else if (markType
== SC_MARK_ARROW
) {
74 Point(centreX
- dimOn4
, centreY
- dimOn2
),
75 Point(centreX
- dimOn4
, centreY
+ dimOn2
),
76 Point(centreX
+ dimOn2
- dimOn4
, centreY
),
78 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
79 fore
.allocated
, back
.allocated
);
81 } else if (markType
== SC_MARK_ARROWDOWN
) {
83 Point(centreX
- dimOn2
, centreY
- dimOn4
),
84 Point(centreX
+ dimOn2
, centreY
- dimOn4
),
85 Point(centreX
, centreY
+ dimOn2
- dimOn4
),
87 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
88 fore
.allocated
, back
.allocated
);
90 } else if (markType
== SC_MARK_PLUS
) {
92 Point(centreX
- armSize
, centreY
- 1),
93 Point(centreX
- 1, centreY
- 1),
94 Point(centreX
- 1, centreY
- armSize
),
95 Point(centreX
+ 1, centreY
- armSize
),
96 Point(centreX
+ 1, centreY
- 1),
97 Point(centreX
+ armSize
, centreY
-1),
98 Point(centreX
+ armSize
, centreY
+1),
99 Point(centreX
+ 1, centreY
+ 1),
100 Point(centreX
+ 1, centreY
+ armSize
),
101 Point(centreX
- 1, centreY
+ armSize
),
102 Point(centreX
- 1, centreY
+ 1),
103 Point(centreX
- armSize
, centreY
+ 1),
105 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
106 fore
.allocated
, back
.allocated
);
108 } else if (markType
== SC_MARK_MINUS
) {
110 Point(centreX
- armSize
, centreY
- 1),
111 Point(centreX
+ armSize
, centreY
-1),
112 Point(centreX
+ armSize
, centreY
+1),
113 Point(centreX
- armSize
, centreY
+ 1),
115 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
116 fore
.allocated
, back
.allocated
);
118 } else if (markType
== SC_MARK_SMALLRECT
) {
120 rcSmall
.left
= rc
.left
+ 1;
121 rcSmall
.top
= rc
.top
+ 2;
122 rcSmall
.right
= rc
.right
- 1;
123 rcSmall
.bottom
= rc
.bottom
- 2;
124 surface
->RectangleDraw(rcSmall
, fore
.allocated
, back
.allocated
);
126 } else if (markType
== SC_MARK_EMPTY
|| markType
== SC_MARK_BACKGROUND
) {
127 // An invisible marker so don't draw anything
129 } else if (markType
== SC_MARK_VLINE
) {
130 surface
->PenColour(back
.allocated
);
131 surface
->MoveTo(centreX
, rcWhole
.top
);
132 surface
->LineTo(centreX
, rcWhole
.bottom
);
134 } else if (markType
== SC_MARK_LCORNER
) {
135 surface
->PenColour(back
.allocated
);
136 surface
->MoveTo(centreX
, rcWhole
.top
);
137 surface
->LineTo(centreX
, rc
.top
+ dimOn2
);
138 surface
->LineTo(rc
.right
- 2, rc
.top
+ dimOn2
);
140 } else if (markType
== SC_MARK_TCORNER
) {
141 surface
->PenColour(back
.allocated
);
142 surface
->MoveTo(centreX
, rcWhole
.top
);
143 surface
->LineTo(centreX
, rcWhole
.bottom
);
144 surface
->MoveTo(centreX
, rc
.top
+ dimOn2
);
145 surface
->LineTo(rc
.right
- 2, rc
.top
+ dimOn2
);
147 } else if (markType
== SC_MARK_LCORNERCURVE
) {
148 surface
->PenColour(back
.allocated
);
149 surface
->MoveTo(centreX
, rcWhole
.top
);
150 surface
->LineTo(centreX
, rc
.top
+ dimOn2
-3);
151 surface
->LineTo(centreX
+3, rc
.top
+ dimOn2
);
152 surface
->LineTo(rc
.right
- 1, rc
.top
+ dimOn2
);
154 } else if (markType
== SC_MARK_TCORNERCURVE
) {
155 surface
->PenColour(back
.allocated
);
156 surface
->MoveTo(centreX
, rcWhole
.top
);
157 surface
->LineTo(centreX
, rcWhole
.bottom
);
159 surface
->MoveTo(centreX
, rc
.top
+ dimOn2
-3);
160 surface
->LineTo(centreX
+3, rc
.top
+ dimOn2
);
161 surface
->LineTo(rc
.right
- 1, rc
.top
+ dimOn2
);
163 } else if (markType
== SC_MARK_BOXPLUS
) {
164 surface
->PenColour(back
.allocated
);
165 DrawBox(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
166 DrawPlus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
168 } else if (markType
== SC_MARK_BOXPLUSCONNECTED
) {
169 surface
->PenColour(back
.allocated
);
170 DrawBox(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
171 DrawPlus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
173 surface
->MoveTo(centreX
, centreY
+ blobSize
);
174 surface
->LineTo(centreX
, rcWhole
.bottom
);
176 surface
->MoveTo(centreX
, rcWhole
.top
);
177 surface
->LineTo(centreX
, centreY
- blobSize
);
179 } else if (markType
== SC_MARK_BOXMINUS
) {
180 surface
->PenColour(back
.allocated
);
181 DrawBox(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
182 DrawMinus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
184 surface
->MoveTo(centreX
, centreY
+ blobSize
);
185 surface
->LineTo(centreX
, rcWhole
.bottom
);
187 } else if (markType
== SC_MARK_BOXMINUSCONNECTED
) {
188 surface
->PenColour(back
.allocated
);
189 DrawBox(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
190 DrawMinus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
192 surface
->MoveTo(centreX
, centreY
+ blobSize
);
193 surface
->LineTo(centreX
, rcWhole
.bottom
);
195 surface
->MoveTo(centreX
, rcWhole
.top
);
196 surface
->LineTo(centreX
, centreY
- blobSize
);
198 } else if (markType
== SC_MARK_CIRCLEPLUS
) {
199 DrawCircle(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
200 surface
->PenColour(back
.allocated
);
201 DrawPlus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
203 } else if (markType
== SC_MARK_CIRCLEPLUSCONNECTED
) {
204 DrawCircle(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
205 surface
->PenColour(back
.allocated
);
206 DrawPlus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
208 surface
->MoveTo(centreX
, centreY
+ blobSize
);
209 surface
->LineTo(centreX
, rcWhole
.bottom
);
211 surface
->MoveTo(centreX
, rcWhole
.top
);
212 surface
->LineTo(centreX
, centreY
- blobSize
);
214 } else if (markType
== SC_MARK_CIRCLEMINUS
) {
215 DrawCircle(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
216 surface
->PenColour(back
.allocated
);
217 DrawMinus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
219 surface
->MoveTo(centreX
, centreY
+ blobSize
);
220 surface
->LineTo(centreX
, rcWhole
.bottom
);
222 } else if (markType
== SC_MARK_CIRCLEMINUSCONNECTED
) {
223 DrawCircle(surface
, centreX
, centreY
, blobSize
, fore
.allocated
, back
.allocated
);
224 surface
->PenColour(back
.allocated
);
225 DrawMinus(surface
, centreX
, centreY
, blobSize
, back
.allocated
);
227 surface
->MoveTo(centreX
, centreY
+ blobSize
);
228 surface
->LineTo(centreX
, rcWhole
.bottom
);
230 surface
->MoveTo(centreX
, rcWhole
.top
);
231 surface
->LineTo(centreX
, centreY
- blobSize
);
233 } else if (markType
>= SC_MARK_CHARACTER
) {
235 character
[0] = static_cast<char>(markType
- SC_MARK_CHARACTER
);
236 int width
= surface
->WidthText(fontForCharacter
, character
, 1);
237 rc
.left
+= (rc
.Width() - width
) / 2;
238 rc
.right
= rc
.left
+ width
;
239 surface
->DrawTextClipped(rc
, fontForCharacter
, rc
.bottom
- 2,
240 character
, 1, fore
.allocated
, back
.allocated
);
242 } else { // SC_MARK_SHORTARROW
244 Point(centreX
, centreY
+ dimOn2
),
245 Point(centreX
+ dimOn2
, centreY
),
246 Point(centreX
, centreY
- dimOn2
),
247 Point(centreX
, centreY
- dimOn4
),
248 Point(centreX
- dimOn4
, centreY
- dimOn4
),
249 Point(centreX
- dimOn4
, centreY
+ dimOn4
),
250 Point(centreX
, centreY
+ dimOn4
),
251 Point(centreX
, centreY
+ dimOn2
),
253 surface
->Polygon(pts
, sizeof(pts
) / sizeof(pts
[0]),
254 fore
.allocated
, back
.allocated
);