1 /* Graphics_colour.cpp
2  *
3  * Copyright (C) 1992-2005,2007-2020 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 
19 #include "GraphicsP.h"
20 
21 #if quartz
22 	#include "macport_on.h"
23 #endif
24 
25 #define wdx(x)  ((x) * my scaleX + my deltaX)
26 #define wdy(y)  ((y) * my scaleY + my deltaY)
27 
_Graphics_setColour(Graphics graphics,MelderColour colour)28 void _Graphics_setColour (Graphics graphics, MelderColour colour) {
29 	if (graphics -> screen) {
30 		GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
31 		#if cairo
32 			if (! my d_cairoGraphicsContext)
33 				return;
34 			cairo_set_source_rgb (my d_cairoGraphicsContext, colour. red, colour. green, colour. blue);
35 		#elif gdi
36 			my d_winForegroundColour = RGB (colour. red * 255, colour. green * 255, colour. blue * 255);
37 			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
38 			DeleteObject (my d_winPen);
39 			my d_winPen = CreatePen (PS_SOLID, 0, my d_winForegroundColour);
40 			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
41 			DeleteObject (my d_winBrush);
42 			my d_winBrush = CreateSolidBrush (my d_winForegroundColour);
43 		#elif quartz
44 			// postpone till drawing
45 		#endif
46 	} else if (graphics -> postScript) {
47 		GraphicsPostscript me = static_cast <GraphicsPostscript> (graphics);
48 		my d_printf (my d_file, "%.6g %.6g %.6g setrgbcolor\n", colour. red, colour. green, colour. blue);
49 	}
50 }
51 
Graphics_setColour(Graphics me,MelderColour colour)52 void Graphics_setColour (Graphics me, MelderColour colour) {
53 	my colour = colour;
54 	_Graphics_setColour (me, colour);
55 	if (my recording) { op (SET_RGB_COLOUR, 3); put (colour. red); put (colour. green); put (colour. blue); }
56 }
57 
Graphics_setColourScale(Graphics me,enum kGraphics_colourScale colourScale)58 void Graphics_setColourScale (Graphics me, enum kGraphics_colourScale colourScale) {
59 	my colourScale = colourScale;
60 	if (my recording) { op (SET_COLOUR_SCALE, 1); put (colourScale); }
61 }
62 
_Graphics_setGrey(Graphics graphics,double fgrey)63 void _Graphics_setGrey (Graphics graphics, double fgrey) {
64 	Melder_clip (0.0, & fgrey, 1.0);
65 	if (graphics -> screen) {
66 		GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
67 		#if cairo
68 			if (! my d_cairoGraphicsContext)
69 				return;
70 			cairo_set_source_rgb (my d_cairoGraphicsContext, fgrey, fgrey, fgrey);
71 		#elif gdi
72 			int lightness = fgrey * 255;
73 			my d_winForegroundColour = RGB (lightness, lightness, lightness);
74 			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
75 			DeleteObject (my d_winPen);
76 			my d_winPen = CreatePen (PS_SOLID, 0, my d_winForegroundColour);
77 			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
78 			DeleteObject (my d_winBrush);
79 			my d_winBrush = CreateSolidBrush (my d_winForegroundColour);
80 		#elif quartz
81 		#endif
82 	} else if (graphics -> postScript) {
83 		GraphicsPostscript me = static_cast <GraphicsPostscript> (graphics);
84 		my d_printf (my d_file, "%.6g setgray\n", fgrey);
85 	}
86 }
87 
Graphics_setGrey(Graphics me,double grey)88 void Graphics_setGrey (Graphics me, double grey) {
89 	my colour. red = my colour. green = my colour. blue = grey;
90 	_Graphics_setGrey (me, grey);
91 	if (my recording) { op (SET_GREY, 1); put (grey); }
92 }
93 
highlight(Graphics graphics,integer x1DC,integer x2DC,integer y1DC,integer y2DC)94 static void highlight (Graphics graphics, integer x1DC, integer x2DC, integer y1DC, integer y2DC) {
95 	if (graphics -> screen) {
96 		GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
97 		#if cairo
98 			if (! my d_cairoGraphicsContext)
99 				return;
100 			int width = x2DC - x1DC, height = y1DC - y2DC;
101 			if (width <= 0 || height <= 0)
102 				return;
103 			if (! my d_cairoGraphicsContext)
104 				return;
105 			cairo_set_source_rgba (my d_cairoGraphicsContext, 1.0, 0.7, 0.7, 0.5);
106 			cairo_rectangle (my d_cairoGraphicsContext, x1DC, y2DC, width, height);
107 			cairo_fill (my d_cairoGraphicsContext);
108 		#elif gdi
109 			static HBRUSH highlightBrush;
110 			RECT rect;
111 			rect. left = x1DC, rect. right = x2DC, rect. top = y2DC, rect. bottom = y1DC;
112 			if (! highlightBrush)
113 				highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
114 			SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
115 			SelectBrush (my d_gdiGraphicsContext, highlightBrush);
116 			SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
117 			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y1DC + 1);
118 			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
119 			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
120 			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));   // superfluous?
121 		#elif quartz
122 			int width = x2DC - x1DC, height = y1DC - y2DC;
123 			if (width <= 0 || height <= 0)
124 				return;
125 			GuiCocoaDrawingArea *drawingArea = (GuiCocoaDrawingArea *) my d_drawingArea -> d_widget;
126 			if (! drawingArea)
127 				return;
128 			NSRect rect = NSMakeRect (x1DC, y2DC, width, height);
129 			CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
130 			if (context) {
131 				CGContextSaveGState (context);
132 				CGContextSetBlendMode (context, kCGBlendModeDarken);
133 				CGContextSetShouldAntialias (context, false);
134 				CGContextSetRGBFillColor (context, 1.0, 0.83, 0.83, 1.0);
135 				CGContextFillRect (context, rect);
136 				CGContextRestoreGState (context);
137 			}
138 		#endif
139 	}
140 }
141 
Graphics_highlight(Graphics me,double x1WC,double x2WC,double y1WC,double y2WC)142 void Graphics_highlight (Graphics me, double x1WC, double x2WC, double y1WC, double y2WC) {
143 	if (my recording) {
144 		op (HIGHLIGHT, 4); put (x1WC); put (x2WC); put (y1WC); put (y2WC);
145 	} else
146 		highlight (me, wdx (x1WC), wdx (x2WC), wdy (y1WC), wdy (y2WC));
147 }
148 
highlight2(Graphics graphics,integer x1DC,integer x2DC,integer y1DC,integer y2DC,integer x1DC_inner,integer x2DC_inner,integer y1DC_inner,integer y2DC_inner)149 static void highlight2 (Graphics graphics, integer x1DC, integer x2DC, integer y1DC, integer y2DC,
150 	integer x1DC_inner, integer x2DC_inner, integer y1DC_inner, integer y2DC_inner)
151 {
152 	if (graphics -> screen) {
153 		GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
154 		#if cairo
155 			if (! my d_cairoGraphicsContext)
156 				return;
157 			int width = x2DC - x1DC, height = y1DC - y2DC;
158 			if (width <= 0 || height <= 0)
159 				return;
160 			cairo_set_source_rgba (my d_cairoGraphicsContext, 1.0, 0.7, 0.7, 0.5);
161 			cairo_rectangle (my d_cairoGraphicsContext, x1DC, y2DC, x2DC - x1DC, y2DC_inner - y2DC); // upper
162 			cairo_rectangle (my d_cairoGraphicsContext, x1DC, y2DC_inner, x1DC_inner - x1DC, y1DC_inner - y2DC_inner); // left part
163 			cairo_rectangle (my d_cairoGraphicsContext, x2DC_inner, y2DC_inner, x2DC - x2DC_inner, y1DC_inner - y2DC_inner); // right part
164 			cairo_rectangle (my d_cairoGraphicsContext, x1DC, y1DC_inner, x2DC - x1DC, y1DC - y1DC_inner); // lower
165 			cairo_fill (my d_cairoGraphicsContext);
166 		#elif gdi
167 			static HBRUSH highlightBrush;
168 			if (! highlightBrush)
169 				highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
170 			SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
171 			SelectBrush (my d_gdiGraphicsContext, highlightBrush);
172 			SetROP2 (my d_gdiGraphicsContext, R2_MASKPEN);
173 			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y2DC_inner + 1);
174 			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC_inner, x1DC_inner + 1, y1DC_inner + 1);
175 			Rectangle (my d_gdiGraphicsContext, x2DC_inner, y2DC_inner, x2DC + 1, y1DC_inner + 1);
176 			Rectangle (my d_gdiGraphicsContext, x1DC, y1DC_inner, x2DC + 1, y1DC + 1);
177 			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
178 			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
179 			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));   // superfluous?
180 		#elif quartz
181 			GuiCocoaDrawingArea *drawingArea = (GuiCocoaDrawingArea *) my d_drawingArea -> d_widget;
182 			if (! drawingArea)
183 				return;
184 			my d_macGraphicsContext = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
185 			CGContextSaveGState (my d_macGraphicsContext);
186 			NSRect upperRect = NSMakeRect (x1DC, y2DC, x2DC - x1DC, y2DC_inner - y2DC);
187 			NSRect leftRect  = NSMakeRect (x1DC, y2DC_inner, x1DC_inner - x1DC, y1DC_inner - y2DC_inner);
188 			NSRect rightRect = NSMakeRect (x2DC_inner, y2DC_inner, x2DC - x2DC_inner, y1DC_inner - y2DC_inner);
189 			NSRect lowerRect = NSMakeRect (x1DC, y1DC_inner, x2DC - x1DC, y1DC - y1DC_inner);
190 			NSColor *colour = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
191 			double red = 0.5 + 0.5 * colour.redComponent, green = 0.5 + 0.5 * colour.greenComponent, blue = 0.5 + 0.5 * colour.blueComponent;
192 			CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeDarken);
193 			CGContextSetRGBFillColor (my d_macGraphicsContext, 1.0, 0.83, 0.83, 1.0);
194 			CGContextFillRect (my d_macGraphicsContext, upperRect);
195 			CGContextFillRect (my d_macGraphicsContext, leftRect);
196 			CGContextFillRect (my d_macGraphicsContext, rightRect);
197 			CGContextFillRect (my d_macGraphicsContext, lowerRect);
198 			CGContextRestoreGState (my d_macGraphicsContext);
199 		#endif
200 	}
201 }
202 
Graphics_highlight2(Graphics me,double x1WC,double x2WC,double y1WC,double y2WC,double x1WC_inner,double x2WC_inner,double y1WC_inner,double y2WC_inner)203 void Graphics_highlight2 (Graphics me, double x1WC, double x2WC, double y1WC, double y2WC,
204 	double x1WC_inner, double x2WC_inner, double y1WC_inner, double y2WC_inner)
205 {
206 	if (my recording) {
207 		op (HIGHLIGHT2, 8);
208 		put (x1WC); put (x2WC); put (y1WC); put (y2WC);
209 		put (x1WC_inner); put (x2WC_inner); put (y1WC_inner); put (y2WC_inner);
210 	} else
211 		highlight2 (me, wdx (x1WC), wdx (x2WC), wdy (y1WC), wdy (y2WC), wdx (x1WC_inner), wdx (x2WC_inner), wdy (y1WC_inner), wdy (y2WC_inner));
212 }
213 
Graphics_xorOn(Graphics graphics,MelderColour colourOnWhiteBackground)214 void Graphics_xorOn (Graphics graphics, MelderColour colourOnWhiteBackground) {
215 	if (graphics -> screen) {
216 		GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
217 		if (my recording) {
218 			op (XOR_ON, 3);
219 			put (colourOnWhiteBackground. red);
220 			put (colourOnWhiteBackground. green);
221 			put (colourOnWhiteBackground. blue);
222 		} else {
223 			my colour. red   = 1.0 - colourOnWhiteBackground. red;
224 			my colour. green = 1.0 - colourOnWhiteBackground. green;
225 			my colour. blue  = 1.0 - colourOnWhiteBackground. blue;
226 			#if cairo
227 				cairo_set_operator (my d_cairoGraphicsContext, CAIRO_OPERATOR_DIFFERENCE);
228 			#elif gdi
229 				SetROP2 (my d_gdiGraphicsContext, R2_XORPEN);
230 			#elif quartz
231 				CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeDifference);
232 			#endif
233 			_Graphics_setColour (me, my colour);
234 			my duringXor = true;
235 		}
236 	}
237 }
238 
Graphics_xorOff(Graphics graphics)239 void Graphics_xorOff (Graphics graphics) {
240 	if (graphics -> screen) {
241 		GraphicsScreen me = static_cast <GraphicsScreen> (graphics);
242 		if (my recording) {
243 			op (XOR_OFF, 0);
244 		} else {
245 			#if cairo
246 				cairo_set_operator (my d_cairoGraphicsContext, CAIRO_OPERATOR_OVER);
247 			#elif gdi
248 				SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
249 			#elif quartz
250 				CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal);
251 			#endif
252 			_Graphics_setColour (me, my colour);
253 			my duringXor = false;
254 		}
255 	}
256 }
257 
Graphics_inqColour(Graphics me)258 MelderColour Graphics_inqColour (Graphics me) {
259 	return my colour;
260 }
261 
Graphics_inqColourScale(Graphics me)262 enum kGraphics_colourScale Graphics_inqColourScale (Graphics me) {
263 	return my colourScale;
264 }
265 
266 /* End of file Graphics_colour.cpp */
267