/scintilla/src/LineMarker.cxx

https://github.com/quiachonj/notepad-plus · C++ · 309 lines · 257 code · 43 blank · 9 comment · 86 complexity · acfc2a5bc13028c8e6dfa4783ba7eecb MD5 · raw file

  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.
  7. #include <string.h>
  8. #include "Platform.h"
  9. #include "Scintilla.h"
  10. #include "XPM.h"
  11. #include "LineMarker.h"
  12. #ifdef SCI_NAMESPACE
  13. using namespace Scintilla;
  14. #endif
  15. void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
  16. pal.WantFind(fore, want);
  17. pal.WantFind(back, want);
  18. if (pxpm) {
  19. pxpm->RefreshColourPalette(pal, want);
  20. }
  21. }
  22. void LineMarker::SetXPM(const char *textForm) {
  23. delete pxpm;
  24. pxpm = new XPM(textForm);
  25. markType = SC_MARK_PIXMAP;
  26. }
  27. void LineMarker::SetXPM(const char * const *linesForm) {
  28. delete pxpm;
  29. pxpm = new XPM(linesForm);
  30. markType = SC_MARK_PIXMAP;
  31. }
  32. static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
  33. PRectangle rc;
  34. rc.left = centreX - armSize;
  35. rc.top = centreY - armSize;
  36. rc.right = centreX + armSize + 1;
  37. rc.bottom = centreY + armSize + 1;
  38. surface->RectangleDraw(rc, back, fore);
  39. }
  40. static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
  41. PRectangle rcCircle;
  42. rcCircle.left = centreX - armSize;
  43. rcCircle.top = centreY - armSize;
  44. rcCircle.right = centreX + armSize + 1;
  45. rcCircle.bottom = centreY + armSize + 1;
  46. surface->Ellipse(rcCircle, back, fore);
  47. }
  48. static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
  49. PRectangle rcV(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1);
  50. surface->FillRectangle(rcV, fore);
  51. PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
  52. surface->FillRectangle(rcH, fore);
  53. }
  54. static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore) {
  55. PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1);
  56. surface->FillRectangle(rcH, fore);
  57. }
  58. void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
  59. if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
  60. pxpm->Draw(surface, rcWhole);
  61. return;
  62. }
  63. // Restrict most shapes a bit
  64. PRectangle rc = rcWhole;
  65. rc.top++;
  66. rc.bottom--;
  67. int minDim = Platform::Minimum(rc.Width(), rc.Height());
  68. minDim--; // Ensure does not go beyond edge
  69. int centreX = (rc.right + rc.left) / 2;
  70. int centreY = (rc.bottom + rc.top) / 2;
  71. int dimOn2 = minDim / 2;
  72. int dimOn4 = minDim / 4;
  73. int blobSize = dimOn2-1;
  74. int armSize = dimOn2-2;
  75. if (rc.Width() > (rc.Height() * 2)) {
  76. // Wide column is line number so move to left to try to avoid overlapping number
  77. centreX = rc.left + dimOn2 + 1;
  78. }
  79. if (markType == SC_MARK_ROUNDRECT) {
  80. PRectangle rcRounded = rc;
  81. rcRounded.left = rc.left + 1;
  82. rcRounded.right = rc.right - 1;
  83. surface->RoundedRectangle(rcRounded, fore.allocated, back.allocated);
  84. } else if (markType == SC_MARK_CIRCLE) {
  85. PRectangle rcCircle;
  86. rcCircle.left = centreX - dimOn2;
  87. rcCircle.top = centreY - dimOn2;
  88. rcCircle.right = centreX + dimOn2;
  89. rcCircle.bottom = centreY + dimOn2;
  90. surface->Ellipse(rcCircle, fore.allocated, back.allocated);
  91. } else if (markType == SC_MARK_ARROW) {
  92. Point pts[] = {
  93. Point(centreX - dimOn4, centreY - dimOn2),
  94. Point(centreX - dimOn4, centreY + dimOn2),
  95. Point(centreX + dimOn2 - dimOn4, centreY),
  96. };
  97. surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
  98. fore.allocated, back.allocated);
  99. } else if (markType == SC_MARK_ARROWDOWN) {
  100. Point pts[] = {
  101. Point(centreX - dimOn2, centreY - dimOn4),
  102. Point(centreX + dimOn2, centreY - dimOn4),
  103. Point(centreX, centreY + dimOn2 - dimOn4),
  104. };
  105. surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
  106. fore.allocated, back.allocated);
  107. } else if (markType == SC_MARK_PLUS) {
  108. Point pts[] = {
  109. Point(centreX - armSize, centreY - 1),
  110. Point(centreX - 1, centreY - 1),
  111. Point(centreX - 1, centreY - armSize),
  112. Point(centreX + 1, centreY - armSize),
  113. Point(centreX + 1, centreY - 1),
  114. Point(centreX + armSize, centreY -1),
  115. Point(centreX + armSize, centreY +1),
  116. Point(centreX + 1, centreY + 1),
  117. Point(centreX + 1, centreY + armSize),
  118. Point(centreX - 1, centreY + armSize),
  119. Point(centreX - 1, centreY + 1),
  120. Point(centreX - armSize, centreY + 1),
  121. };
  122. surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
  123. fore.allocated, back.allocated);
  124. } else if (markType == SC_MARK_MINUS) {
  125. Point pts[] = {
  126. Point(centreX - armSize, centreY - 1),
  127. Point(centreX + armSize, centreY -1),
  128. Point(centreX + armSize, centreY +1),
  129. Point(centreX - armSize, centreY + 1),
  130. };
  131. surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
  132. fore.allocated, back.allocated);
  133. } else if (markType == SC_MARK_SMALLRECT) {
  134. PRectangle rcSmall;
  135. rcSmall.left = rc.left + 1;
  136. rcSmall.top = rc.top + 2;
  137. rcSmall.right = rc.right - 1;
  138. rcSmall.bottom = rc.bottom - 2;
  139. surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
  140. } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
  141. // An invisible marker so don't draw anything
  142. } else if (markType == SC_MARK_VLINE) {
  143. surface->PenColour(back.allocated);
  144. surface->MoveTo(centreX, rcWhole.top);
  145. surface->LineTo(centreX, rcWhole.bottom);
  146. } else if (markType == SC_MARK_LCORNER) {
  147. surface->PenColour(back.allocated);
  148. surface->MoveTo(centreX, rcWhole.top);
  149. surface->LineTo(centreX, rc.top + dimOn2);
  150. surface->LineTo(rc.right - 2, rc.top + dimOn2);
  151. } else if (markType == SC_MARK_TCORNER) {
  152. surface->PenColour(back.allocated);
  153. surface->MoveTo(centreX, rcWhole.top);
  154. surface->LineTo(centreX, rcWhole.bottom);
  155. surface->MoveTo(centreX, rc.top + dimOn2);
  156. surface->LineTo(rc.right - 2, rc.top + dimOn2);
  157. } else if (markType == SC_MARK_LCORNERCURVE) {
  158. surface->PenColour(back.allocated);
  159. surface->MoveTo(centreX, rcWhole.top);
  160. surface->LineTo(centreX, rc.top + dimOn2-3);
  161. surface->LineTo(centreX+3, rc.top + dimOn2);
  162. surface->LineTo(rc.right - 1, rc.top + dimOn2);
  163. } else if (markType == SC_MARK_TCORNERCURVE) {
  164. surface->PenColour(back.allocated);
  165. surface->MoveTo(centreX, rcWhole.top);
  166. surface->LineTo(centreX, rcWhole.bottom);
  167. surface->MoveTo(centreX, rc.top + dimOn2-3);
  168. surface->LineTo(centreX+3, rc.top + dimOn2);
  169. surface->LineTo(rc.right - 1, rc.top + dimOn2);
  170. } else if (markType == SC_MARK_BOXPLUS) {
  171. surface->PenColour(back.allocated);
  172. DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  173. DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
  174. } else if (markType == SC_MARK_BOXPLUSCONNECTED) {
  175. surface->PenColour(back.allocated);
  176. DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  177. DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
  178. surface->MoveTo(centreX, centreY + blobSize);
  179. surface->LineTo(centreX, rcWhole.bottom);
  180. surface->MoveTo(centreX, rcWhole.top);
  181. surface->LineTo(centreX, centreY - blobSize);
  182. } else if (markType == SC_MARK_BOXMINUS) {
  183. surface->PenColour(back.allocated);
  184. DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  185. DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
  186. surface->MoveTo(centreX, centreY + blobSize);
  187. surface->LineTo(centreX, rcWhole.bottom);
  188. } else if (markType == SC_MARK_BOXMINUSCONNECTED) {
  189. surface->PenColour(back.allocated);
  190. DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  191. DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
  192. surface->MoveTo(centreX, centreY + blobSize);
  193. surface->LineTo(centreX, rcWhole.bottom);
  194. surface->MoveTo(centreX, rcWhole.top);
  195. surface->LineTo(centreX, centreY - blobSize);
  196. } else if (markType == SC_MARK_CIRCLEPLUS) {
  197. DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  198. surface->PenColour(back.allocated);
  199. DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
  200. } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
  201. DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  202. surface->PenColour(back.allocated);
  203. DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
  204. surface->MoveTo(centreX, centreY + blobSize);
  205. surface->LineTo(centreX, rcWhole.bottom);
  206. surface->MoveTo(centreX, rcWhole.top);
  207. surface->LineTo(centreX, centreY - blobSize);
  208. } else if (markType == SC_MARK_CIRCLEMINUS) {
  209. DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  210. surface->PenColour(back.allocated);
  211. DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
  212. surface->MoveTo(centreX, centreY + blobSize);
  213. surface->LineTo(centreX, rcWhole.bottom);
  214. } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
  215. DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
  216. surface->PenColour(back.allocated);
  217. DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
  218. surface->MoveTo(centreX, centreY + blobSize);
  219. surface->LineTo(centreX, rcWhole.bottom);
  220. surface->MoveTo(centreX, rcWhole.top);
  221. surface->LineTo(centreX, centreY - blobSize);
  222. } else if (markType >= SC_MARK_CHARACTER) {
  223. char character[1];
  224. character[0] = static_cast<char>(markType - SC_MARK_CHARACTER);
  225. int width = surface->WidthText(fontForCharacter, character, 1);
  226. rc.left += (rc.Width() - width) / 2;
  227. rc.right = rc.left + width;
  228. surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2,
  229. character, 1, fore.allocated, back.allocated);
  230. } else if (markType == SC_MARK_DOTDOTDOT) {
  231. int right = centreX - 6;
  232. for (int b=0; b<3; b++) {
  233. PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2);
  234. surface->FillRectangle(rcBlob, fore.allocated);
  235. right += 5;
  236. }
  237. } else if (markType == SC_MARK_ARROWS) {
  238. surface->PenColour(fore.allocated);
  239. int right = centreX - 2;
  240. for (int b=0; b<3; b++) {
  241. surface->MoveTo(right - 4, centreY - 4);
  242. surface->LineTo(right, centreY);
  243. surface->LineTo(right - 5, centreY + 5);
  244. right += 4;
  245. }
  246. } else if (markType == SC_MARK_SHORTARROW) {
  247. Point pts[] = {
  248. Point(centreX, centreY + dimOn2),
  249. Point(centreX + dimOn2, centreY),
  250. Point(centreX, centreY - dimOn2),
  251. Point(centreX, centreY - dimOn4),
  252. Point(centreX - dimOn4, centreY - dimOn4),
  253. Point(centreX - dimOn4, centreY + dimOn4),
  254. Point(centreX, centreY + dimOn4),
  255. Point(centreX, centreY + dimOn2),
  256. };
  257. surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
  258. fore.allocated, back.allocated);
  259. } else if (markType == SC_MARK_LEFTRECT) {
  260. PRectangle rcLeft = rcWhole;
  261. rcLeft.right = rcLeft.left + 4;
  262. surface->FillRectangle(rcLeft, back.allocated);
  263. } else { // SC_MARK_FULLRECT
  264. surface->FillRectangle(rcWhole, back.allocated);
  265. }
  266. }