Graphics_colour.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /* Graphics_colour.cpp
  2. *
  3. * Copyright (C) 1992-2005,2007-2018 Paul Boersma, 2013 Tom Naughton
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "GraphicsP.h"
  19. #include <stdint.h>
  20. Graphics_Colour
  21. Graphics_BLACK = { 0.0, 0.0, 0.0 },
  22. Graphics_WHITE = { 1.0, 1.0, 1.0 },
  23. Graphics_RED = { 0.865, 0.034, 0.026 },
  24. Graphics_GREEN = { 0.000, 0.500, 0.069 },
  25. Graphics_BLUE = { 0.000, 0.000, 0.828 },
  26. Graphics_CYAN = { 0.009, 0.669, 0.918 },
  27. Graphics_MAGENTA = { 0.949, 0.033, 0.519 },
  28. Graphics_YELLOW = { 0.984, 0.951, 0.020 },
  29. Graphics_MAROON = { 0.5, 0.0, 0.0 },
  30. Graphics_LIME = { 0.0, 1.0, 0.0 },
  31. Graphics_NAVY = { 0.0, 0.0, 0.5 },
  32. Graphics_TEAL = { 0.0, 0.5, 0.5 },
  33. Graphics_PURPLE = { 0.5, 0.0, 0.5 },
  34. Graphics_OLIVE = { 0.5, 0.5, 0.0 },
  35. Graphics_PINK = { 1.0, 0.75, 0.75 },
  36. Graphics_SILVER = { 0.75, 0.75, 0.75 },
  37. Graphics_GREY = { 0.5, 0.5, 0.5 },
  38. Graphics_WINDOW_BACKGROUND_COLOUR = { 0.90, 0.90, 0.85 };
  39. inline static conststring32 rgbColourName (Graphics_Colour colour) {
  40. static MelderString buffer { };
  41. MelderString_copy (& buffer,
  42. U"{", Melder_fixed (colour. red, 6),
  43. U",", Melder_fixed (colour. green, 6),
  44. U",", Melder_fixed (colour. blue, 6),
  45. U"}"
  46. );
  47. return buffer.string;
  48. }
  49. conststring32 Graphics_Colour_name (Graphics_Colour colour) {
  50. return
  51. Graphics_Colour_equal (colour, Graphics_BLACK) ? U"black" :
  52. Graphics_Colour_equal (colour, Graphics_WHITE) ? U"white" :
  53. Graphics_Colour_equal (colour, Graphics_RED) ? U"red" :
  54. Graphics_Colour_equal (colour, Graphics_GREEN) ? U"green" :
  55. Graphics_Colour_equal (colour, Graphics_BLUE) ? U"blue" :
  56. Graphics_Colour_equal (colour, Graphics_CYAN) ? U"cyan" :
  57. Graphics_Colour_equal (colour, Graphics_MAGENTA) ? U"magenta" :
  58. Graphics_Colour_equal (colour, Graphics_YELLOW) ? U"yellow" :
  59. Graphics_Colour_equal (colour, Graphics_MAROON) ? U"maroon" :
  60. Graphics_Colour_equal (colour, Graphics_LIME) ? U"lime" :
  61. Graphics_Colour_equal (colour, Graphics_NAVY) ? U"navy" :
  62. Graphics_Colour_equal (colour, Graphics_TEAL) ? U"teal" :
  63. Graphics_Colour_equal (colour, Graphics_PURPLE) ? U"purple" :
  64. Graphics_Colour_equal (colour, Graphics_OLIVE) ? U"olive" :
  65. Graphics_Colour_equal (colour, Graphics_SILVER) ? U"silver" :
  66. Graphics_Colour_equal (colour, Graphics_GREY) ? U"grey" :
  67. rgbColourName (colour);
  68. }
  69. constexpr int theNumberOfCyclingColours = 10;
  70. static Graphics_Colour theCyclingBackgroundColours [theNumberOfCyclingColours] = {
  71. Graphics_GREEN, Graphics_SILVER, Graphics_BLUE, Graphics_YELLOW, Graphics_RED,
  72. Graphics_CYAN, Graphics_MAROON, Graphics_LIME, Graphics_TEAL, Graphics_MAGENTA
  73. };
  74. static Graphics_Colour theCyclingTextColours [theNumberOfCyclingColours] = {
  75. Graphics_WHITE, Graphics_BLACK, Graphics_WHITE, Graphics_BLACK, Graphics_WHITE,
  76. Graphics_BLACK, Graphics_WHITE, Graphics_BLACK, Graphics_WHITE, Graphics_BLACK
  77. };
  78. Graphics_Colour Graphics_cyclingBackgroundColour (integer category) {
  79. return theCyclingBackgroundColours [(category - 1) % theNumberOfCyclingColours];
  80. }
  81. Graphics_Colour Graphics_cyclingTextColour (integer category) {
  82. return theCyclingTextColours [(category - 1) % theNumberOfCyclingColours];
  83. }
  84. #if quartz
  85. #include "macport_on.h"
  86. #endif
  87. #define wdx(x) ((x) * my scaleX + my deltaX)
  88. #define wdy(y) ((y) * my scaleY + my deltaY)
  89. void _Graphics_setColour (Graphics graphics, Graphics_Colour colour) {
  90. if (graphics -> screen) {
  91. GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
  92. #if cairo
  93. if (! my d_cairoGraphicsContext) return;
  94. cairo_set_source_rgb (my d_cairoGraphicsContext, colour. red, colour. green, colour. blue);
  95. #elif gdi
  96. my d_winForegroundColour = RGB (colour. red * 255, colour. green * 255, colour. blue * 255);
  97. SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
  98. DeleteObject (my d_winPen);
  99. my d_winPen = CreatePen (PS_SOLID, 0, my d_winForegroundColour);
  100. SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
  101. DeleteObject (my d_winBrush);
  102. my d_winBrush = CreateSolidBrush (my d_winForegroundColour);
  103. #elif quartz
  104. my d_macColour. red = colour. red * 65535;
  105. my d_macColour. green = colour. green * 65535;
  106. my d_macColour. blue = colour. blue * 65535;
  107. // postpone till drawing
  108. #endif
  109. } else if (graphics -> postScript) {
  110. GraphicsPostscript me = static_cast <GraphicsPostscript> (graphics);
  111. my d_printf (my d_file, "%.6g %.6g %.6g setrgbcolor\n", colour. red, colour. green, colour. blue);
  112. }
  113. }
  114. void Graphics_setColour (Graphics me, Graphics_Colour colour) {
  115. my colour = colour;
  116. _Graphics_setColour (me, colour);
  117. if (my recording) { op (SET_RGB_COLOUR, 3); put (colour. red); put (colour. green); put (colour. blue); }
  118. }
  119. void Graphics_setColourScale (Graphics me, enum kGraphics_colourScale colourScale) {
  120. my colourScale = colourScale;
  121. if (my recording) { op (SET_COLOUR_SCALE, 1); put (colourScale); }
  122. }
  123. void _Graphics_setGrey (Graphics graphics, double fgrey) {
  124. if (graphics -> screen) {
  125. GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
  126. #if cairo
  127. if (! my d_cairoGraphicsContext) return;
  128. if (fgrey < 0.0) fgrey = 0.0; else if (fgrey > 1.0) fgrey = 1.0;
  129. cairo_set_source_rgb (my d_cairoGraphicsContext, fgrey, fgrey, fgrey);
  130. #elif gdi
  131. int lightness = fgrey <= 0 ? 0 : fgrey >= 1.0 ? 255 : fgrey * 255;
  132. my d_winForegroundColour = RGB (lightness, lightness, lightness);
  133. SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
  134. DeleteObject (my d_winPen);
  135. my d_winPen = CreatePen (PS_SOLID, 0, my d_winForegroundColour);
  136. SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
  137. DeleteObject (my d_winBrush);
  138. my d_winBrush = CreateSolidBrush (my d_winForegroundColour);
  139. #elif quartz
  140. if (fgrey < 0.0) fgrey = 0.0; else if (fgrey > 1.0) fgrey = 1.0;
  141. my d_macColour. red = my d_macColour. green = my d_macColour. blue = fgrey * 65535;
  142. #endif
  143. } else if (graphics -> postScript) {
  144. GraphicsPostscript me = static_cast <GraphicsPostscript> (graphics);
  145. if (fgrey < 0.0) fgrey = 0.0; else if (fgrey > 1.0) fgrey = 1.0;
  146. my d_printf (my d_file, "%.6g setgray\n", fgrey);
  147. }
  148. }
  149. void Graphics_setGrey (Graphics me, double grey) {
  150. my colour. red = my colour. green = my colour. blue = grey;
  151. _Graphics_setGrey (me, grey);
  152. if (my recording) { op (SET_GREY, 1); put (grey); }
  153. }
  154. static void highlight (Graphics graphics, integer x1DC, integer x2DC, integer y1DC, integer y2DC, int direction) {
  155. if (graphics -> screen) {
  156. GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
  157. #if cairo
  158. if (! my d_cairoGraphicsContext) return;
  159. int width = x2DC - x1DC, height = y1DC - y2DC;
  160. if (width <= 0 || height <= 0) return;
  161. #if ALLOW_GDK_DRAWING
  162. gdk_gc_set_function (my d_gdkGraphicsContext, GDK_XOR);
  163. GdkColor pinkXorWhite = { 0, 0x0000, 0x4000, 0x4000 }, black = { 0, 0x0000, 0x0000, 0x0000 };
  164. gdk_gc_set_rgb_fg_color (my d_gdkGraphicsContext, & pinkXorWhite);
  165. gdk_draw_rectangle (my d_window, my d_gdkGraphicsContext, true, x1DC, y2DC, width, height);
  166. gdk_gc_set_rgb_fg_color (my d_gdkGraphicsContext, & black);
  167. gdk_gc_set_function (my d_gdkGraphicsContext, GDK_COPY);
  168. gdk_flush ();
  169. #endif
  170. #elif gdi
  171. static HBRUSH highlightBrush;
  172. RECT rect;
  173. rect. left = x1DC, rect. right = x2DC, rect. top = y2DC, rect. bottom = y1DC;
  174. if (! highlightBrush)
  175. highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
  176. SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
  177. SelectBrush (my d_gdiGraphicsContext, highlightBrush);
  178. SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
  179. Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y1DC + 1);
  180. SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
  181. SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
  182. SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH)); // superfluous?
  183. #elif quartz
  184. int width = x2DC - x1DC, height = y1DC - y2DC;
  185. if (width <= 0 || height <= 0) return;
  186. GuiCocoaDrawingArea *drawingArea = (GuiCocoaDrawingArea *) my d_drawingArea -> d_widget;
  187. if (drawingArea) {
  188. bool cacheImageInRectWillWork = ( Melder_systemVersion < 101100 || Melder_systemVersion > 101106 );
  189. if (cacheImageInRectWillWork) {
  190. NSView *nsView = my d_macView;
  191. if (direction == 1) { // forward
  192. NSRect rect = NSMakeRect (x1DC, y2DC, width, height);
  193. NSRect windowRect = [nsView convertRect: rect toView: nil];
  194. //NSRect windowRect = [nsView convertRectToBacking: rect];
  195. //NSRect windowRect = [nsView backingAlignedRect: rect options: NSAlignAllEdgesNearest];
  196. //windowRect.origin.x += 1;
  197. //windowRect.size.width -= 2;
  198. [[nsView window] cacheImageInRect: windowRect];
  199. [drawingArea lockFocus];
  200. CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
  201. CGContextSaveGState (context);
  202. //CGContextSetBlendMode (context, kCGBlendModeDifference);
  203. CGContextSetBlendMode (context, kCGBlendModeDarken);
  204. CGContextSetShouldAntialias (context, false);
  205. NSColor *colour = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName: NSDeviceRGBColorSpace];
  206. double red = 0.5 + 0.5 * colour.redComponent, green = 0.5 + 0.5 * colour.greenComponent, blue = 0.5 + 0.5 * colour.blueComponent;
  207. //CGContextSetRGBFillColor (context, 1.0 - red, 1.0 - green, 1.0 - blue, 1.0);
  208. CGContextSetRGBFillColor (context, red, green, blue, 1.0);
  209. CGContextFillRect (context, rect);
  210. CGContextRestoreGState (context);
  211. [drawingArea unlockFocus];
  212. //GuiShell_drain (nullptr);
  213. } else { // backward
  214. //[drawingArea lockFocus];
  215. [[nsView window] restoreCachedImage];
  216. //[[nsView window] discardCachedImage];
  217. //[drawingArea unlockFocus];
  218. //[[nsView window] flushWindow];
  219. //[[nsView window] flushWindowIfNeeded];
  220. }
  221. } else {
  222. [drawingArea lockFocus];
  223. CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
  224. CGContextSaveGState (context);
  225. NSCAssert (context, @"nil context");
  226. //CGContextTranslateCTM (context, 0, drawingArea. bounds. size. height);
  227. //CGContextScaleCTM (context, 1.0, -1.0);
  228. NSRect rect = NSMakeRect (x1DC, y2DC, width, height);
  229. CGContextSetBlendMode (context, kCGBlendModeDifference);
  230. CGContextSetShouldAntialias (context, false);
  231. NSColor *colour = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
  232. double red = 0.5 + 0.5 * colour.redComponent, green = 0.5 + 0.5 * colour.greenComponent, blue = 0.5 + 0.5 * colour.blueComponent;
  233. if (direction == 1) { // forward
  234. CGContextSetRGBFillColor (context, 1.0 - red, 1.0 - green, 1.0 - blue, 1.0);
  235. CGContextFillRect (context, rect);
  236. } else { // backward
  237. CGContextSetRGBFillColor (context, red, green, blue, 1.0);
  238. CGContextFillRect (context, rect);
  239. CGContextSetRGBFillColor (context, 1.0, 1.0, 1.0, 1.0);
  240. CGContextFillRect (context, rect);
  241. }
  242. CGContextRestoreGState (context);
  243. //CGContextSynchronize (context);
  244. [drawingArea unlockFocus];
  245. }
  246. }
  247. #endif
  248. }
  249. }
  250. void Graphics_highlight (Graphics me, double x1WC, double x2WC, double y1WC, double y2WC) {
  251. highlight (me, wdx (x1WC), wdx (x2WC), wdy (y1WC), wdy (y2WC), 1);
  252. if (my recording)
  253. { op (HIGHLIGHT, 4); put (x1WC); put (x2WC); put (y1WC); put (y2WC); }
  254. }
  255. void Graphics_unhighlight (Graphics me, double x1WC, double x2WC, double y1WC, double y2WC) {
  256. highlight (me, wdx (x1WC), wdx (x2WC), wdy (y1WC), wdy (y2WC), 2);
  257. if (my recording)
  258. { op (UNHIGHLIGHT, 4); put (x1WC); put (x2WC); put (y1WC); put (y2WC); }
  259. }
  260. static void highlight2 (Graphics graphics, integer x1DC, integer x2DC, integer y1DC, integer y2DC,
  261. integer x1DC_inner, integer x2DC_inner, integer y1DC_inner, integer y2DC_inner, int direction)
  262. {
  263. if (graphics -> screen) {
  264. GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
  265. #if cairo
  266. if (! my d_cairoGraphicsContext) return;
  267. int width = x2DC - x1DC, height = y1DC - y2DC;
  268. if (width <= 0 || height <= 0) return;
  269. #if ALLOW_GDK_DRAWING
  270. gdk_gc_set_function (my d_gdkGraphicsContext, GDK_XOR);
  271. GdkColor pinkXorWhite = { 0, 0x0000, 0x4000, 0x4000 }, black = { 0, 0x0000, 0x0000, 0x0000 };
  272. gdk_gc_set_rgb_fg_color (my d_gdkGraphicsContext, & pinkXorWhite);
  273. gdk_draw_rectangle (my d_window, my d_gdkGraphicsContext, true, x1DC, y2DC, x2DC - x1DC, y2DC_inner - y2DC); // upper
  274. gdk_draw_rectangle (my d_window, my d_gdkGraphicsContext, true, x1DC, y2DC_inner, x1DC_inner - x1DC, y1DC_inner - y2DC_inner); // left part
  275. gdk_draw_rectangle (my d_window, my d_gdkGraphicsContext, true, x2DC_inner, y2DC_inner, x2DC - x2DC_inner, y1DC_inner - y2DC_inner); // right part
  276. gdk_draw_rectangle (my d_window, my d_gdkGraphicsContext, true, x1DC, y1DC_inner, x2DC - x1DC, y1DC - y1DC_inner); // lower
  277. gdk_gc_set_rgb_fg_color (my d_gdkGraphicsContext, & black);
  278. gdk_gc_set_function (my d_gdkGraphicsContext, GDK_COPY);
  279. gdk_flush ();
  280. #endif
  281. #elif gdi
  282. static HBRUSH highlightBrush;
  283. if (! highlightBrush)
  284. highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
  285. SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
  286. SelectBrush (my d_gdiGraphicsContext, highlightBrush);
  287. SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
  288. Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y2DC_inner + 1);
  289. Rectangle (my d_gdiGraphicsContext, x1DC, y2DC_inner, x1DC_inner + 1, y1DC_inner + 1);
  290. Rectangle (my d_gdiGraphicsContext, x2DC_inner, y2DC_inner, x2DC + 1, y1DC_inner + 1);
  291. Rectangle (my d_gdiGraphicsContext, x1DC, y1DC_inner, x2DC + 1, y1DC + 1);
  292. SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
  293. SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
  294. SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH)); // superfluous?
  295. #elif quartz
  296. GuiCocoaDrawingArea *drawingArea = (GuiCocoaDrawingArea *) my d_drawingArea -> d_widget;
  297. if (drawingArea) {
  298. bool cacheImageInRectWillWork = ( Melder_systemVersion < 101100 || Melder_systemVersion > 101106 );
  299. if (cacheImageInRectWillWork) {
  300. NSView *nsView = my d_macView;
  301. if (direction == 1) {
  302. NSRect rect = Melder_systemVersion < 101100 &&0 ?
  303. NSMakeRect (x1DC, y2DC,
  304. x2DC - x1DC /*[nsView visibleRect].size.width*/,
  305. y1DC - y2DC /*[nsView visibleRect].size.height*/) :
  306. [nsView visibleRect];
  307. NSRect windowRect = [nsView convertRect: rect toView: nil];
  308. Melder_assert ([nsView window] != nil);
  309. [[nsView window] cacheImageInRect: windowRect];
  310. } else {
  311. [[nsView window] restoreCachedImage];
  312. //[[nsView window] flushWindow];
  313. return;
  314. }
  315. }
  316. [drawingArea lockFocus];
  317. my d_macGraphicsContext = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
  318. CGContextSaveGState (my d_macGraphicsContext);
  319. NSRect upperRect = NSMakeRect (x1DC, y2DC, x2DC - x1DC, y2DC_inner - y2DC);
  320. NSRect leftRect = NSMakeRect (x1DC, y2DC_inner, x1DC_inner - x1DC, y1DC_inner - y2DC_inner);
  321. NSRect rightRect = NSMakeRect (x2DC_inner, y2DC_inner, x2DC - x2DC_inner, y1DC_inner - y2DC_inner);
  322. NSRect lowerRect = NSMakeRect (x1DC, y1DC_inner, x2DC - x1DC, y1DC - y1DC_inner);
  323. NSColor *colour = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
  324. double red = 0.5 + 0.5 * colour.redComponent, green = 0.5 + 0.5 * colour.greenComponent, blue = 0.5 + 0.5 * colour.blueComponent;
  325. if (cacheImageInRectWillWork) {
  326. CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeDarken);
  327. CGContextSetRGBFillColor (my d_macGraphicsContext, red, green, blue, 1.0);
  328. CGContextFillRect (my d_macGraphicsContext, upperRect);
  329. CGContextFillRect (my d_macGraphicsContext, leftRect);
  330. CGContextFillRect (my d_macGraphicsContext, rightRect);
  331. CGContextFillRect (my d_macGraphicsContext, lowerRect);
  332. } else if (1) {
  333. /*
  334. An older, suboptimal method.
  335. */
  336. CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeDifference);
  337. if (direction == 1) {
  338. CGContextSetRGBFillColor (my d_macGraphicsContext, 1.0 - red, 1.0 - green, 1.0 - blue, 1.0);
  339. CGContextFillRect (my d_macGraphicsContext, upperRect);
  340. CGContextFillRect (my d_macGraphicsContext, leftRect);
  341. CGContextFillRect (my d_macGraphicsContext, rightRect);
  342. CGContextFillRect (my d_macGraphicsContext, lowerRect);
  343. } else {
  344. CGContextSetRGBFillColor (my d_macGraphicsContext, red, green, blue, 1.0);
  345. CGContextFillRect (my d_macGraphicsContext, upperRect);
  346. CGContextFillRect (my d_macGraphicsContext, leftRect);
  347. CGContextFillRect (my d_macGraphicsContext, rightRect);
  348. CGContextFillRect (my d_macGraphicsContext, lowerRect);
  349. CGContextSetRGBFillColor (my d_macGraphicsContext, 1.0, 1.0, 1.0, 1.0);
  350. CGContextFillRect (my d_macGraphicsContext, upperRect);
  351. CGContextFillRect (my d_macGraphicsContext, leftRect);
  352. CGContextFillRect (my d_macGraphicsContext, rightRect);
  353. CGContextFillRect (my d_macGraphicsContext, lowerRect);
  354. }
  355. } else if (1) {
  356. /*
  357. This is true XOR.
  358. */
  359. CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeDifference);
  360. CGContextSetRGBFillColor (my d_macGraphicsContext, 1.0, 1.0, 1.0, 1.0);
  361. CGContextFillRect (my d_macGraphicsContext, upperRect);
  362. CGContextFillRect (my d_macGraphicsContext, leftRect);
  363. CGContextFillRect (my d_macGraphicsContext, rightRect);
  364. CGContextFillRect (my d_macGraphicsContext, lowerRect);
  365. }
  366. CGContextRestoreGState (my d_macGraphicsContext);
  367. [drawingArea unlockFocus];
  368. }
  369. #endif
  370. }
  371. }
  372. void Graphics_highlight2 (Graphics me, double x1WC, double x2WC, double y1WC, double y2WC,
  373. double x1WC_inner, double x2WC_inner, double y1WC_inner, double y2WC_inner)
  374. {
  375. highlight2 (me, wdx (x1WC), wdx (x2WC), wdy (y1WC), wdy (y2WC), wdx (x1WC_inner), wdx (x2WC_inner), wdy (y1WC_inner), wdy (y2WC_inner), 1);
  376. if (my recording)
  377. { op (HIGHLIGHT2, 8); put (x1WC); put (x2WC); put (y1WC); put (y2WC); put (x1WC_inner); put (x2WC_inner); put (y1WC_inner); put (y2WC_inner); }
  378. }
  379. void Graphics_unhighlight2 (Graphics me, double x1WC, double x2WC, double y1WC, double y2WC,
  380. double x1WC_inner, double x2WC_inner, double y1WC_inner, double y2WC_inner)
  381. {
  382. highlight2 (me, wdx (x1WC), wdx (x2WC), wdy (y1WC), wdy (y2WC), wdx (x1WC_inner), wdx (x2WC_inner), wdy (y1WC_inner), wdy (y2WC_inner), 2);
  383. if (my recording)
  384. { op (UNHIGHLIGHT2, 8); put (x1WC); put (x2WC); put (y1WC); put (y2WC); put (x1WC_inner); put (x2WC_inner); put (y1WC_inner); put (y2WC_inner); }
  385. }
  386. void Graphics_xorOn (Graphics graphics, Graphics_Colour colour) {
  387. if (graphics -> screen) {
  388. GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
  389. #if cairo
  390. #if ALLOW_GDK_DRAWING
  391. GdkColor colourXorWhite { 0,
  392. (uint16) ((uint16) (colour. red * 65535.0) ^ (uint16) 0xFFFF),
  393. (uint16) ((uint16) (colour. green * 65535.0) ^ (uint16) 0xFFFF),
  394. (uint16) ((uint16) (colour. blue * 65535.0) ^ (uint16) 0xFFFF) };
  395. gdk_gc_set_rgb_fg_color (my d_gdkGraphicsContext, & colourXorWhite);
  396. gdk_gc_set_function (my d_gdkGraphicsContext, GDK_XOR);
  397. gdk_flush ();
  398. #else
  399. cairo_set_source_rgba (my d_cairoGraphicsContext, 1.0, 0.8, 0.8, 0.5);
  400. cairo_set_operator (my d_cairoGraphicsContext, CAIRO_OPERATOR_XOR);
  401. #endif
  402. #elif gdi
  403. SetROP2 (my d_gdiGraphicsContext, R2_XORPEN);
  404. colour. red = ((uint16) (colour. red * 65535.0) ^ 0xFFFF) / 65535.0;
  405. colour. green = ((uint16) (colour. green * 65535.0) ^ 0xFFFF) / 65535.0;
  406. colour. blue = ((uint16) (colour. blue * 65535.0) ^ 0xFFFF) / 65535.0;
  407. _Graphics_setColour (me, colour);
  408. #elif quartz
  409. #endif
  410. my duringXor = true;
  411. if (graphics -> recording) { op (XOR_ON, 3); put (colour. red); put (colour. green); put (colour. blue); }
  412. }
  413. }
  414. void Graphics_xorOff (Graphics graphics) {
  415. if (graphics -> screen) {
  416. GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
  417. #if cairo
  418. #if ALLOW_GDK_DRAWING
  419. GdkColor black { 0, 0x0000, 0x0000, 0x0000 };
  420. gdk_gc_set_rgb_fg_color (my d_gdkGraphicsContext, & black);
  421. gdk_gc_set_function (my d_gdkGraphicsContext, GDK_COPY);
  422. gdk_flush (); // to undraw the last drawing
  423. #else
  424. cairo_set_source_rgba (my d_cairoGraphicsContext, 0.0, 0.0, 0.0, 1.0);
  425. cairo_set_operator (my d_cairoGraphicsContext, CAIRO_OPERATOR_OVER);
  426. #endif
  427. #elif gdi
  428. SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
  429. _Graphics_setColour (me, my colour);
  430. #elif quartz
  431. //Graphics_flushWs (graphics); // to undraw the last drawing
  432. #endif
  433. my duringXor = false;
  434. if (graphics -> recording) { op (XOR_OFF, 0); }
  435. }
  436. }
  437. Graphics_Colour Graphics_inqColour (Graphics me) {
  438. return my colour;
  439. }
  440. enum kGraphics_colourScale Graphics_inqColourScale (Graphics me) {
  441. return my colourScale;
  442. }
  443. /* End of file Graphics_colour.cpp */