]>
Commit | Line | Data |
---|---|---|
9ce192d4 | 1 | // Scintilla source code edit control |
65ec6247 RD |
2 | /** @file LineMarker.cxx |
3 | ** Defines the look of a line marker in the margin . | |
4 | **/ | |
5 | // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> | |
9ce192d4 RD |
6 | // The License.txt file describes the conditions under which this software may be distributed. |
7 | ||
8 | #include "Platform.h" | |
9 | ||
10 | #include "Scintilla.h" | |
11 | #include "LineMarker.h" | |
12 | ||
65ec6247 RD |
13 | static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, Colour fore, Colour back) { |
14 | PRectangle rc; | |
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); | |
20 | } | |
21 | ||
22 | static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, Colour fore, Colour back) { | |
23 | PRectangle rcCircle; | |
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); | |
29 | } | |
30 | ||
31 | static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, Colour 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); | |
36 | } | |
37 | ||
38 | static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, Colour fore) { | |
39 | PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1); | |
40 | surface->FillRectangle(rcH, fore); | |
41 | } | |
42 | ||
b8b0e402 | 43 | void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) { |
65ec6247 RD |
44 | // Restrict most shapes a bit |
45 | PRectangle rc = rcWhole; | |
46 | rc.top++; | |
47 | rc.bottom--; | |
9ce192d4 RD |
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; | |
65ec6247 RD |
54 | int blobSize = dimOn2-1; |
55 | int armSize = dimOn2-2; | |
9ce192d4 RD |
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; | |
59 | } | |
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) { | |
66 | PRectangle rcCircle; | |
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) { | |
73 | Point pts[] = { | |
74 | Point(centreX - dimOn4, centreY - dimOn2), | |
75 | Point(centreX - dimOn4, centreY + dimOn2), | |
76 | Point(centreX + dimOn2 - dimOn4, centreY), | |
77 | }; | |
78 | surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), | |
79 | fore.allocated, back.allocated); | |
80 | ||
81 | } else if (markType == SC_MARK_ARROWDOWN) { | |
82 | Point pts[] = { | |
83 | Point(centreX - dimOn2, centreY - dimOn4), | |
84 | Point(centreX + dimOn2, centreY - dimOn4), | |
85 | Point(centreX, centreY + dimOn2 - dimOn4), | |
86 | }; | |
87 | surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), | |
88 | fore.allocated, back.allocated); | |
89 | ||
90 | } else if (markType == SC_MARK_PLUS) { | |
9ce192d4 RD |
91 | Point pts[] = { |
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), | |
104 | }; | |
105 | surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), | |
106 | fore.allocated, back.allocated); | |
107 | ||
108 | } else if (markType == SC_MARK_MINUS) { | |
9ce192d4 RD |
109 | Point pts[] = { |
110 | Point(centreX - armSize, centreY - 1), | |
111 | Point(centreX + armSize, centreY -1), | |
112 | Point(centreX + armSize, centreY +1), | |
113 | Point(centreX - armSize, centreY + 1), | |
114 | }; | |
9ce192d4 RD |
115 | surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), |
116 | fore.allocated, back.allocated); | |
117 | ||
118 | } else if (markType == SC_MARK_SMALLRECT) { | |
119 | PRectangle rcSmall; | |
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); | |
65ec6247 | 125 | |
9ce192d4 RD |
126 | } else if (markType == SC_MARK_EMPTY) { |
127 | // An invisible marker so don't draw anything | |
65ec6247 RD |
128 | |
129 | } else if (markType == SC_MARK_VLINE) { | |
130 | surface->PenColour(back.allocated); | |
131 | surface->MoveTo(centreX, rcWhole.top); | |
132 | surface->LineTo(centreX, rcWhole.bottom); | |
133 | ||
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); | |
139 | ||
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); | |
146 | ||
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); | |
153 | ||
154 | } else if (markType == SC_MARK_TCORNERCURVE) { | |
155 | surface->PenColour(back.allocated); | |
156 | surface->MoveTo(centreX, rcWhole.top); | |
157 | surface->LineTo(centreX, rcWhole.bottom); | |
158 | ||
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); | |
162 | ||
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); | |
167 | ||
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); | |
172 | ||
173 | surface->MoveTo(centreX, centreY + blobSize); | |
174 | surface->LineTo(centreX, rcWhole.bottom); | |
175 | ||
176 | surface->MoveTo(centreX, rcWhole.top); | |
177 | surface->LineTo(centreX, centreY - blobSize); | |
178 | ||
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); | |
183 | ||
184 | surface->MoveTo(centreX, centreY + blobSize); | |
185 | surface->LineTo(centreX, rcWhole.bottom); | |
186 | ||
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); | |
191 | ||
192 | surface->MoveTo(centreX, centreY + blobSize); | |
193 | surface->LineTo(centreX, rcWhole.bottom); | |
194 | ||
195 | surface->MoveTo(centreX, rcWhole.top); | |
196 | surface->LineTo(centreX, centreY - blobSize); | |
197 | ||
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); | |
202 | ||
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); | |
207 | ||
208 | surface->MoveTo(centreX, centreY + blobSize); | |
209 | surface->LineTo(centreX, rcWhole.bottom); | |
210 | ||
211 | surface->MoveTo(centreX, rcWhole.top); | |
212 | surface->LineTo(centreX, centreY - blobSize); | |
213 | ||
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); | |
218 | ||
219 | surface->MoveTo(centreX, centreY + blobSize); | |
220 | surface->LineTo(centreX, rcWhole.bottom); | |
221 | ||
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); | |
226 | ||
227 | surface->MoveTo(centreX, centreY + blobSize); | |
228 | surface->LineTo(centreX, rcWhole.bottom); | |
229 | ||
230 | surface->MoveTo(centreX, rcWhole.top); | |
231 | surface->LineTo(centreX, centreY - blobSize); | |
232 | ||
b8b0e402 RD |
233 | } else if (markType >= SC_MARK_CHARACTER) { |
234 | char character[1]; | |
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); | |
241 | ||
9ce192d4 RD |
242 | } else { // SC_MARK_SHORTARROW |
243 | Point pts[] = { | |
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), | |
252 | }; | |
253 | surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), | |
254 | fore.allocated, back.allocated); | |
255 | } | |
256 | } |