*** empty log message ***
[anjuta-git-plugin.git] / scintilla / LineMarker.cxx
blobec9c86f74f2f8c208fc03dd86b79895a2a8446b1
1 // Scintilla source code edit control
2 /** @file LineMarker.cxx
3 ** Defines the look of a line marker in the margin .
4 **/
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.
8 #include <string.h>
10 #include "Platform.h"
12 #include "Scintilla.h"
13 #include "XPM.h"
14 #include "LineMarker.h"
16 void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
17 pal.WantFind(fore, want);
18 pal.WantFind(back, want);
19 if (pxpm) {
20 pxpm->RefreshColourPalette(pal, want);
24 void LineMarker::SetXPM(const char *textForm) {
25 delete pxpm;
26 pxpm = new XPM(textForm);
27 markType = SC_MARK_PIXMAP;
30 void LineMarker::SetXPM(const char * const *linesForm) {
31 delete pxpm;
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) {
37 PRectangle rc;
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) {
46 PRectangle rcCircle;
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);
69 return;
71 // Restrict most shapes a bit
72 PRectangle rc = rcWhole;
73 rc.top++;
74 rc.bottom--;
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) {
93 PRectangle rcCircle;
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) {
100 Point pts[] = {
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) {
109 Point pts[] = {
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) {
118 Point pts[] = {
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) {
136 Point pts[] = {
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) {
146 PRectangle rcSmall;
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) {
261 char character[1];
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);
274 right += 5;
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);
283 right += 4;
285 } else { // SC_MARK_SHORTARROW
286 Point pts[] = {
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);