scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
[anjuta-extras.git] / plugins / scintilla / scintilla / LineMarker.cxx
blob73410e2cd863e1bc1e09187bfb6e4e60152dad39
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-2011 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 #ifdef SCI_NAMESPACE
17 using namespace Scintilla;
18 #endif
20 void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
21 pal.WantFind(fore, want);
22 pal.WantFind(back, want);
23 pal.WantFind(backSelected, want);
24 if (pxpm) {
25 pxpm->RefreshColourPalette(pal, want);
29 void LineMarker::SetXPM(const char *textForm) {
30 delete pxpm;
31 pxpm = new XPM(textForm);
32 markType = SC_MARK_PIXMAP;
35 void LineMarker::SetXPM(const char *const *linesForm) {
36 delete pxpm;
37 pxpm = new XPM(linesForm);
38 markType = SC_MARK_PIXMAP;
41 static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
42 PRectangle rc;
43 rc.left = centreX - armSize;
44 rc.top = centreY - armSize;
45 rc.right = centreX + armSize + 1;
46 rc.bottom = centreY + armSize + 1;
47 surface->RectangleDraw(rc, back, fore);
50 static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
51 PRectangle rcCircle;
52 rcCircle.left = centreX - armSize;
53 rcCircle.top = centreY - armSize;
54 rcCircle.right = centreX + armSize + 1;
55 rcCircle.bottom = centreY + armSize + 1;
56 surface->Ellipse(rcCircle, back, fore);
59 static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
60 PRectangle rcV(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1);
61 surface->FillRectangle(rcV, fore);
62 PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
63 surface->FillRectangle(rcH, fore);
66 static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
67 PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
68 surface->FillRectangle(rcH, fore);
71 void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
72 ColourPair head = back;
73 ColourPair body = back;
74 ColourPair tail = back;
76 switch (tFold) {
77 case LineMarker::head :
78 head = backSelected;
79 tail = backSelected;
80 if (markType == SC_MARK_VLINE)
81 body = backSelected;
82 break;
83 case LineMarker::body :
84 head = backSelected;
85 body = backSelected;
86 break;
87 case LineMarker::tail :
88 body = backSelected;
89 tail = backSelected;
90 break;
91 default :
92 // LineMarker::undefined
93 break;
97 if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
98 pxpm->Draw(surface, rcWhole);
99 return;
101 // Restrict most shapes a bit
102 PRectangle rc = rcWhole;
103 rc.top++;
104 rc.bottom--;
105 int minDim = Platform::Minimum(rc.Width(), rc.Height());
106 minDim--; // Ensure does not go beyond edge
107 int centreX = (rc.right + rc.left) / 2;
108 int centreY = (rc.bottom + rc.top) / 2;
109 int dimOn2 = minDim / 2;
110 int dimOn4 = minDim / 4;
111 int blobSize = dimOn2-1;
112 int armSize = dimOn2-2;
113 if (rc.Width() > (rc.Height() * 2)) {
114 // Wide column is line number so move to left to try to avoid overlapping number
115 centreX = rc.left + dimOn2 + 1;
117 if (markType == SC_MARK_ROUNDRECT) {
118 PRectangle rcRounded = rc;
119 rcRounded.left = rc.left + 1;
120 rcRounded.right = rc.right - 1;
121 surface->RoundedRectangle(rcRounded, fore.allocated, back.allocated);
122 } else if (markType == SC_MARK_CIRCLE) {
123 PRectangle rcCircle;
124 rcCircle.left = centreX - dimOn2;
125 rcCircle.top = centreY - dimOn2;
126 rcCircle.right = centreX + dimOn2;
127 rcCircle.bottom = centreY + dimOn2;
128 surface->Ellipse(rcCircle, fore.allocated, back.allocated);
129 } else if (markType == SC_MARK_ARROW) {
130 Point pts[] = {
131 Point(centreX - dimOn4, centreY - dimOn2),
132 Point(centreX - dimOn4, centreY + dimOn2),
133 Point(centreX + dimOn2 - dimOn4, centreY),
135 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
136 fore.allocated, back.allocated);
138 } else if (markType == SC_MARK_ARROWDOWN) {
139 Point pts[] = {
140 Point(centreX - dimOn2, centreY - dimOn4),
141 Point(centreX + dimOn2, centreY - dimOn4),
142 Point(centreX, centreY + dimOn2 - dimOn4),
144 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
145 fore.allocated, back.allocated);
147 } else if (markType == SC_MARK_PLUS) {
148 Point pts[] = {
149 Point(centreX - armSize, centreY - 1),
150 Point(centreX - 1, centreY - 1),
151 Point(centreX - 1, centreY - armSize),
152 Point(centreX + 1, centreY - armSize),
153 Point(centreX + 1, centreY - 1),
154 Point(centreX + armSize, centreY -1),
155 Point(centreX + armSize, centreY +1),
156 Point(centreX + 1, centreY + 1),
157 Point(centreX + 1, centreY + armSize),
158 Point(centreX - 1, centreY + armSize),
159 Point(centreX - 1, centreY + 1),
160 Point(centreX - armSize, centreY + 1),
162 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
163 fore.allocated, back.allocated);
165 } else if (markType == SC_MARK_MINUS) {
166 Point pts[] = {
167 Point(centreX - armSize, centreY - 1),
168 Point(centreX + armSize, centreY -1),
169 Point(centreX + armSize, centreY +1),
170 Point(centreX - armSize, centreY + 1),
172 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
173 fore.allocated, back.allocated);
175 } else if (markType == SC_MARK_SMALLRECT) {
176 PRectangle rcSmall;
177 rcSmall.left = rc.left + 1;
178 rcSmall.top = rc.top + 2;
179 rcSmall.right = rc.right - 1;
180 rcSmall.bottom = rc.bottom - 2;
181 surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
183 } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
184 markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
185 // An invisible marker so don't draw anything
187 } else if (markType == SC_MARK_VLINE) {
188 surface->PenColour(body.allocated);
189 surface->MoveTo(centreX, rcWhole.top + blobSize - (rcWhole.bottom - rcWhole.top)/2);
190 surface->LineTo(centreX, rcWhole.bottom);
192 } else if (markType == SC_MARK_LCORNER) {
193 surface->PenColour(tail.allocated);
194 surface->MoveTo(centreX, rcWhole.top);
195 surface->LineTo(centreX, rc.top + dimOn2);
196 surface->LineTo(rc.right - 2, rc.top + dimOn2);
198 } else if (markType == SC_MARK_TCORNER) {
199 surface->PenColour(tail.allocated);
200 surface->MoveTo(centreX, rc.top + dimOn2);
201 surface->LineTo(rc.right - 2, rc.top + dimOn2);
203 surface->PenColour(body.allocated);
204 surface->MoveTo(centreX, rcWhole.top);
205 surface->LineTo(centreX, rc.top + dimOn2 + 1);
207 surface->PenColour(head.allocated);
208 surface->LineTo(centreX, rcWhole.bottom);
210 } else if (markType == SC_MARK_LCORNERCURVE) {
211 surface->PenColour(tail.allocated);
212 surface->MoveTo(centreX, rcWhole.top);
213 surface->LineTo(centreX, rc.top + dimOn2-3);
214 surface->LineTo(centreX+3, rc.top + dimOn2);
215 surface->LineTo(rc.right - 1, rc.top + dimOn2);
217 } else if (markType == SC_MARK_TCORNERCURVE) {
218 surface->PenColour(tail.allocated);
219 surface->MoveTo(centreX, rc.top + dimOn2-3);
220 surface->LineTo(centreX+3, rc.top + dimOn2);
221 surface->LineTo(rc.right - 1, rc.top + dimOn2);
223 surface->PenColour(body.allocated);
224 surface->MoveTo(centreX, rcWhole.top);
225 surface->LineTo(centreX, rc.top + dimOn2-2);
227 surface->PenColour(head.allocated);
228 surface->LineTo(centreX, rcWhole.bottom);
230 } else if (markType == SC_MARK_BOXPLUS) {
231 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
232 DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
234 } else if (markType == SC_MARK_BOXPLUSCONNECTED) {
235 surface->PenColour(body.allocated);
236 surface->MoveTo(centreX, centreY + blobSize);
237 surface->LineTo(centreX, rcWhole.bottom);
239 surface->PenColour(body.allocated);
240 surface->MoveTo(centreX, rcWhole.top);
241 surface->LineTo(centreX, centreY - blobSize);
243 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
244 DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
246 if (tFold == LineMarker::body) {
247 surface->PenColour(tail.allocated);
248 surface->MoveTo(centreX + 1, centreY + blobSize);
249 surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
251 surface->MoveTo(centreX + blobSize, centreY + blobSize);
252 surface->LineTo(centreX + blobSize, centreY - blobSize);
254 surface->MoveTo(centreX + 1, centreY - blobSize);
255 surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
257 } else if (markType == SC_MARK_BOXMINUS) {
258 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
259 DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
261 surface->PenColour(head.allocated);
262 surface->MoveTo(centreX, centreY + blobSize);
263 surface->LineTo(centreX, rcWhole.bottom);
265 } else if (markType == SC_MARK_BOXMINUSCONNECTED) {
266 DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
267 DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
269 surface->PenColour(head.allocated);
270 surface->MoveTo(centreX, centreY + blobSize);
271 surface->LineTo(centreX, rcWhole.bottom);
273 surface->PenColour(body.allocated);
274 surface->MoveTo(centreX, rcWhole.top);
275 surface->LineTo(centreX, centreY - blobSize);
277 if (tFold == LineMarker::body) {
278 surface->PenColour(tail.allocated);
279 surface->MoveTo(centreX + 1, centreY + blobSize);
280 surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
282 surface->MoveTo(centreX + blobSize, centreY + blobSize);
283 surface->LineTo(centreX + blobSize, centreY - blobSize);
285 surface->MoveTo(centreX + 1, centreY - blobSize);
286 surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
288 } else if (markType == SC_MARK_CIRCLEPLUS) {
289 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
290 DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
292 } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
293 surface->PenColour(body.allocated);
294 surface->MoveTo(centreX, centreY + blobSize);
295 surface->LineTo(centreX, rcWhole.bottom);
297 surface->MoveTo(centreX, rcWhole.top);
298 surface->LineTo(centreX, centreY - blobSize);
300 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
301 DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
303 } else if (markType == SC_MARK_CIRCLEMINUS) {
304 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
305 DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
307 surface->PenColour(head.allocated);
308 surface->MoveTo(centreX, centreY + blobSize);
309 surface->LineTo(centreX, rcWhole.bottom);
311 } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
312 DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
313 DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
315 surface->PenColour(head.allocated);
316 surface->MoveTo(centreX, centreY + blobSize);
317 surface->LineTo(centreX, rcWhole.bottom);
319 surface->PenColour(body.allocated);
320 surface->MoveTo(centreX, rcWhole.top);
321 surface->LineTo(centreX, centreY - blobSize);
323 } else if (markType >= SC_MARK_CHARACTER) {
324 char character[1];
325 character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
326 int width = surface->WidthText(fontForCharacter, character, 1);
327 rc.left += (rc.Width() - width) / 2;
328 rc.right = rc.left + width;
329 surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
330 character, 1, fore.allocated, back.allocated);
332 } else if (markType == SC_MARK_DOTDOTDOT) {
333 int right = centreX - 6;
334 for (int b=0; b<3; b++) {
335 PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
336 surface->FillRectangle(rcBlob, fore.allocated);
337 right += 5;
339 } else if (markType == SC_MARK_ARROWS) {
340 surface->PenColour(fore.allocated);
341 int right = centreX - 2;
342 for (int b=0; b<3; b++) {
343 surface->MoveTo(right - 4, centreY - 4);
344 surface->LineTo(right, centreY);
345 surface->LineTo(right - 5, centreY + 5);
346 right += 4;
348 } else if (markType == SC_MARK_SHORTARROW) {
349 Point pts[] = {
350 Point(centreX, centreY + dimOn2),
351 Point(centreX + dimOn2, centreY),
352 Point(centreX, centreY - dimOn2),
353 Point(centreX, centreY - dimOn4),
354 Point(centreX - dimOn4, centreY - dimOn4),
355 Point(centreX - dimOn4, centreY + dimOn4),
356 Point(centreX, centreY + dimOn4),
357 Point(centreX, centreY + dimOn2),
359 surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
360 fore.allocated, back.allocated);
361 } else if (markType == SC_MARK_LEFTRECT) {
362 PRectangle rcLeft = rcWhole;
363 rcLeft.right = rcLeft.left + 4;
364 surface->FillRectangle(rcLeft, back.allocated);
365 } else { // SC_MARK_FULLRECT
366 surface->FillRectangle(rcWhole, back.allocated);