1 #include "win32\win32guts.h"
2 #ifndef _APRICOT_H_
3 #include "apricot.h"
4 #endif
5 #include "guts.h"
6 #include "Window.h"
7 #include "Icon.h"
8 #include "DeviceBitmap.h"
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14
15 #define sys (( PDrawableData)(( PComponent) self)-> sysData)->
16 #define dsys( view) (( PDrawableData)(( PComponent) view)-> sysData)->
17 #define var (( PWidget) self)->
18 #define HANDLE sys handle
19 #define DHANDLE(x) dsys(x) handle
20
21 Bool
apc_gp_init(Handle self)22 apc_gp_init( Handle self)
23 {
24 objCheck false;
25 sys lineWidth = 1.0;
26 return true;
27 }
28
29 Bool
apc_gp_done(Handle self)30 apc_gp_done( Handle self)
31 {
32 objCheck false;
33 aa_free_arena(self, 0);
34 if ( sys bm)
35 if ( !DeleteObject( sys bm)) apiErr;
36 if ( sys pal)
37 if ( !DeleteObject( sys pal)) apiErr;
38 if ( sys graphics) {
39 GdipDeleteGraphics(sys graphics);
40 sys graphics = NULL;
41 }
42 if ( sys ps) {
43 if ( is_apt( aptWinPS) && is_apt( aptWM_PAINT)) {
44 if ( !EndPaint(( HWND) var handle, &sys paintStruc)) apiErr;
45 } else if ( is_apt( aptWinPS)) {
46 if ( self == application)
47 dc_free();
48 else {
49 if ( !ReleaseDC(( HWND) var handle, sys ps)) apiErr;
50 }
51 }
52 }
53 if ( sys linePatternLen > sizeof(sys linePattern)) free( sys linePattern);
54 stylus_free( sys stylusResource, false); /* XXX check this */
55 stylus_gp_free( sys stylusGPResource, false);
56 if ( sys linePatternLen > sizeof(sys linePattern)) free( sys linePattern);
57 font_free( sys fontResource, false);
58 if ( sys p256) free( sys p256);
59 sys bm = NULL;
60 sys pal = NULL;
61 sys ps = NULL;
62 sys bm = NULL;
63 sys p256 = NULL;
64 sys fontResource = NULL;
65 sys stylusResource = NULL;
66 sys stylusGPResource = NULL;
67 sys linePattern = NULL;
68 return true;
69 }
70
71 #define ADJUST_LINE_END_DEF(typ) \
72 void \
73 adjust_line_end_##typ \
74 ( typ x1, typ y1, typ *x2, typ *y2) \
75 { \
76 if ( x1 == *x2) \
77 ( y1 < *y2) ? ( *y2)++ : ( *y2)--; \
78 else if ( y1 == *y2) \
79 ( x1 < *x2) ? ( *x2)++ : ( *x2)--; \
80 else { \
81 long tan = ( *y2 - y1) * 1000L / ( *x2 - x1); \
82 if ( tan < 1000 && tan > -1000) { \
83 typ dx = *x2 - x1; \
84 ( dx > 0) ? dx++ : dx--; \
85 *x2 = x1 + dx; \
86 *y2 = (typ)( y1 + dx * tan / 1000L); \
87 } else { \
88 typ dy = *y2 - y1; \
89 ( dy > 0) ? dy++ : dy--; \
90 *x2 = (typ)( x1 + dy * 1000L / tan); \
91 *y2 = y1 + dy; \
92 } \
93 } \
94 } \
95
96 ADJUST_LINE_END_DEF(int);
97 ADJUST_LINE_END_DEF(LONG);
98
99 static Bool
gp_Arc(Handle self,int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2,double angleStart,double angleEnd)100 gp_Arc(
101 Handle self,
102 int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,
103 int nXRadial1, int nYRadial1, int nXRadial2, int nYRadial2,
104 double angleStart, double angleEnd
105 ) {
106 if ( nXRadial1 == nXRadial2 && nYRadial1 == nYRadial2 && fabs(angleStart - angleEnd) < 360 ) {
107 Bool ret;
108 HGDIOBJ old;
109
110 old = SelectObject( sys ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
111 adjust_line_end_int( nXRadial1, nYRadial1, &nXRadial2, &nYRadial2);
112 MoveToEx( sys ps, nXRadial1, nYRadial1, NULL);
113 ret = LineTo( sys ps, nXRadial2, nYRadial2);
114 DeleteObject(SelectObject( sys ps, old) );
115 return ret;
116 } else {
117 return Arc(
118 sys ps,
119 nLeftRect, nTopRect, nRightRect, nBottomRect,
120 nXRadial1, nYRadial1, nXRadial2, nYRadial2
121 );
122 }
123 }
124
125 static Bool
gp_Chord(Handle self,int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2,double angleStart,double angleEnd,Bool filled)126 gp_Chord(
127 Handle self,
128 int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,
129 int nXRadial1, int nYRadial1, int nXRadial2, int nYRadial2,
130 double angleStart, double angleEnd, Bool filled
131 ) {
132 if (
133 (abs(nXRadial1 - nXRadial2) < 2) &&
134 (abs(nYRadial1 == nYRadial2) < 2) &&
135 (fabs(angleStart - angleEnd) < 360 )
136 ) {
137 Bool ret;
138 HGDIOBJ old;
139
140 if ( filled ) {
141 nXRadial2--;
142 nYRadial2--;
143 }
144
145 old = SelectObject( sys ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
146 adjust_line_end_int( nXRadial1, nYRadial1, &nXRadial2, &nYRadial2);
147 MoveToEx( sys ps, nXRadial1, nYRadial1, NULL);
148 ret = LineTo( sys ps, nXRadial2, nYRadial2);
149 DeleteObject(SelectObject( sys ps, old) );
150 return ret;
151 } else {
152 return Chord(
153 sys ps,
154 nLeftRect, nTopRect, nRightRect, nBottomRect,
155 nXRadial1, nYRadial1, nXRadial2, nYRadial2
156 );
157 }
158 }
159
160 static Bool
gp_Pie(Handle self,int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2,double angleStart,double angleEnd,Bool filled)161 gp_Pie(
162 Handle self,
163 int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,
164 int nXRadial1, int nYRadial1, int nXRadial2, int nYRadial2,
165 double angleStart, double angleEnd, Bool filled
166 ) {
167 if ( nXRadial1 == nXRadial2 && nYRadial1 == nYRadial2 && fabs(angleStart - angleEnd) < 360 ) {
168 int cx, cy;
169 Bool ret;
170 HGDIOBJ old;
171
172 old = SelectObject( sys ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
173 cx = ( nLeftRect + nRightRect ) / 2;
174 cy = ( nTopRect + nBottomRect ) / 2;
175 adjust_line_end_int( cx, cy, &nXRadial1, &nYRadial1);
176 if ( filled ) {
177 if ( nXRadial2 > cx ) nXRadial1 = nXRadial2;
178 if ( nYRadial2 > cy ) nYRadial1 = nYRadial2;
179 }
180 MoveToEx( sys ps, cx, cy, NULL);
181 ret = LineTo( sys ps, nXRadial1, nYRadial1);
182 DeleteObject(SelectObject( sys ps, old) );
183 return ret;
184 } else {
185 return Pie(
186 sys ps,
187 nLeftRect, nTopRect, nRightRect, nBottomRect,
188 nXRadial1, nYRadial1, nXRadial2, nYRadial2
189 );
190 }
191 }
192
193
194 #define GRAD 57.29577951
195
196 #define check_swap( parm1, parm2) if ( parm1 > parm2) { int parm3 = parm1; parm1 = parm2; parm2 = parm3;}
197
198 #define ELLIPSE_RECT (int)(x - ( dX - 1) / 2), (int)(y - dY / 2), (int)(x + dX / 2 + 1), (int)(y + (dY - 1) / 2 + 1)
199 #define ELLIPSE_RECT_SUPERINCLUSIVE (int)(x - ( dX - 1) / 2), (int)(y - dY / 2), (int)(x + dX / 2 + 2), (int)(y + (dY - 1) / 2 + 2)
200 #define ARC_COMPLETE (int)(x + dX / 2 + 1), y, (int)(x + dX / 2 + 1), y
201 #define ARC_ANGLED (int)(x + cos( angleStart / GRAD) * dX / 2 + 0.5), (int)(y - sin( angleStart / GRAD) * dY / 2 + 0.5), \
202 (int)(x + cos( angleEnd / GRAD) * dX / 2 + 0.5), (int)(y - sin( angleEnd / GRAD) * dY / 2 + 0.5)
203 #define ARC_ANGLED_SUPERINCLUSIVE (int)(x + cos( angleStart / GRAD) * dX / 2 + 0.5), (int)(y - sin( angleStart / GRAD) * dY / 2 + 0.5), \
204 (int)(x + cos( angleEnd / GRAD) * dX / 2 + 1.5), (int)(y - sin( angleEnd / GRAD) * dY / 2 + 1.5)
205
206 #define EMULATE_OPAQUE_LINE \
207 (sys stylus. pen. lopnStyle == PS_USERSTYLE && sys currentROP2 == ropCopyPut)
208 #define STYLUS_USE_OPAQUE_LINE \
209 sys stylusFlags &=~ stbPen;\
210 if ( !sys opaquePen) sys opaquePen = CreatePen( PS_SOLID, sys stylus.pen.lopnWidth.x, sys lbs[1]);\
211 SelectObject(sys ps, sys opaquePen);\
212 if (sys currentROP != R2_COPYPEN) SetROP2( sys ps, R2_COPYPEN)
213 #define STYLUS_RESTORE_OPAQUE_LINE if (sys currentROP != R2_COPYPEN) SetROP2( sys ps, sys currentROP)
214
215 Bool
apc_gp_arc(Handle self,int x,int y,int dX,int dY,double angleStart,double angleEnd)216 apc_gp_arc( Handle self, int x, int y, int dX, int dY, double angleStart, double angleEnd)
217 { objCheck false; {
218 int compl, needf;
219 HDC ps = sys ps;
220
221 SHIFT_XY(x,y);
222 compl = arc_completion( &angleStart, &angleEnd, &needf);
223
224 if (EMULATE_OPAQUE_LINE) {
225 STYLUS_USE_OPAQUE_LINE;
226 if ( compl )
227 Arc( ps, ELLIPSE_RECT, ARC_COMPLETE);
228 else
229 gp_Arc( self, ELLIPSE_RECT, ARC_ANGLED, angleStart, angleEnd);
230 STYLUS_RESTORE_OPAQUE_LINE;
231 }
232
233 STYLUS_USE_PEN( ps);
234 while( compl--)
235 Arc( ps, ELLIPSE_RECT, ARC_COMPLETE);
236 if ( !needf) return true;
237 if ( !gp_Arc( self, ELLIPSE_RECT, ARC_ANGLED, angleStart, angleEnd)) apiErrRet;
238 return true;
239 }}
240
241 Bool
apc_gp_bar(Handle self,int x1,int y1,int x2,int y2)242 apc_gp_bar( Handle self, int x1, int y1, int x2, int y2)
243 {objCheck false;{
244 HDC ps = sys ps;
245 HGDIOBJ old;
246 Bool ok;
247
248 check_swap( x1, x2);
249 check_swap( y1, y2);
250 SHIFT_XY(x1,y1);
251 SHIFT_XY(x2,y2);
252
253 ok = true;
254 old = SelectObject( ps, hPenHollow);
255 STYLUS_USE_BRUSH( ps);
256
257 if ( !( ok = Rectangle( ps, x1, y2, x2 + 2, y1 + 2)))
258 apiErr;
259 SelectObject( ps, old);
260 return ok;
261 }}
262
263 Bool
apc_gp_bars(Handle self,int nr,Rect * rr)264 apc_gp_bars( Handle self, int nr, Rect *rr)
265 {objCheck false;{
266 HDC ps = sys ps;
267 HGDIOBJ old = SelectObject( ps, hPenHollow);
268 Bool ok = true;
269 int i;
270 STYLUS_USE_BRUSH( ps);
271 for ( i = 0; i < nr; i++, rr++) {
272 Rect xr = *rr;
273 check_swap( xr.left, xr.right);
274 check_swap( xr.bottom, xr.top);
275 SHIFT_XY( xr.left, xr.bottom);
276 SHIFT_XY( xr.right, xr.top);
277 if ( !( ok = Rectangle( ps, xr.left, xr.top, xr.left + 2, xr.bottom + 2))) {
278 apiErr;
279 break;
280 }
281 }
282 SelectObject( ps, old);
283 return ok;
284 }}
285
286 Bool
apc_gp_alpha(Handle self,int alpha,int x1,int y1,int x2,int y2)287 apc_gp_alpha( Handle self, int alpha, int x1, int y1, int x2, int y2)
288 {objCheck false;{
289 Bool ok;
290 HDC dc, buf_dc;
291 HBITMAP buf_bm, old_bm;
292 unsigned int dst_lw, y, w, h;
293 Byte *dst;
294
295 if ( !(
296 (is_apt(aptDeviceBitmap) && ((PDeviceBitmap)self)->type == dbtLayered) ||
297 is_apt(aptLayered) ||
298 ( apc_widget_get_layered_request(self) && apc_widget_surface_is_layered(self))
299 ))
300 return false;
301
302 if ( x1 < 0 && y1 < 0 && x2 < 0 && y2 < 0) {
303 x1 = y1 = 0;
304 x2 = sys lastSize. x - 1;
305 y2 = sys lastSize. y - 1;
306 }
307 check_swap( x1, x2);
308 check_swap( y1, y2);
309 w = x2 - x1 + 1;
310 h = y2 - y1 + 1;
311
312 y1 = y2;
313 SHIFT_XY(x1,y1);
314
315 dc = GetDC(NULL);
316 buf_dc = CreateCompatibleDC(dc);
317 if ( !(buf_bm = image_create_argb_dib_section(dc, w, h, (uint32_t**) &dst))) {
318 DeleteDC(buf_dc);
319 ReleaseDC(NULL, dc);
320 return false;
321 }
322
323 old_bm = SelectObject(buf_dc, buf_bm);
324 if ( !( ok = BitBlt( buf_dc, 0, 0, w, h, sys ps, x1, y1, SRCCOPY))) {
325 apiErr;
326 goto EXIT;
327 }
328
329 dst_lw = w * 4;
330 for ( y = 0; y < h; y++, dst += dst_lw ) {
331 register Byte *dd = dst + 3;
332 register unsigned int ww = w;
333 while (ww--) {
334 *dd = alpha;
335 dd += 4;
336 }
337 }
338
339 if ( !( ok = BitBlt( sys ps, x1, y1, w, h, buf_dc, 0, 0, SRCCOPY)))
340 apiErr;
341
342 EXIT:
343 SelectObject(buf_dc, old_bm);
344 DeleteDC(buf_dc);
345 DeleteObject(buf_bm);
346 ReleaseDC(NULL, dc);
347
348 return ok;
349 }}
350
351 Bool
apc_gp_can_draw_alpha(Handle self)352 apc_gp_can_draw_alpha( Handle self)
353 {
354 objCheck false;
355 if ( is_apt(aptDeviceBitmap))
356 return ((PDeviceBitmap)self)->type != dbtBitmap;
357 else if ( is_apt( aptImage ))
358 return ((PImage)self)-> type != imBW;
359 else
360 return true;
361 }
362
363 Bool
apc_gp_clear(Handle self,int x1,int y1,int x2,int y2)364 apc_gp_clear( Handle self, int x1, int y1, int x2, int y2)
365 {objCheck false;{
366 Bool ok = true;
367 HDC ps = sys ps;
368 HGDIOBJ oldp = SelectObject( ps, hPenHollow);
369 LOGBRUSH ers;
370 HGDIOBJ oldh;
371 ers. lbStyle = PS_SOLID;
372 ers. lbColor = sys lbs[ 1];
373 ers. lbHatch = 0;
374 oldh = CreateBrushIndirect( &ers);
375 oldh = SelectObject( ps, oldh);
376 if ( x1 < 0 && y1 < 0 && x2 < 0 && y2 < 0) {
377 x1 = y1 = 0;
378 x2 = sys lastSize. x - 1;
379 y2 = sys lastSize. y - 1;
380 }
381 check_swap( x1, x2);
382 check_swap( y1, y2);
383 SHIFT_XY(x1,y1);
384 SHIFT_XY(x2,y2);
385 if ( !( ok = Rectangle( sys ps, x1, y2, x2 + 2, y1 + 2)))
386 apiErr;
387 SelectObject( ps, oldp);
388 DeleteObject( SelectObject( ps, oldh));
389 return ok;
390 }}
391
392 Bool
apc_gp_chord(Handle self,int x,int y,int dX,int dY,double angleStart,double angleEnd)393 apc_gp_chord( Handle self, int x, int y, int dX, int dY, double angleStart, double angleEnd)
394 {objCheck false;{
395 Bool ok = true;
396 HDC ps = sys ps;
397 HGDIOBJ old = SelectObject( ps, hBrushHollow);
398 int compl, needf;
399 compl = arc_completion( &angleStart, &angleEnd, &needf);
400
401 SHIFT_XY(x,y);
402
403 if (EMULATE_OPAQUE_LINE) {
404 STYLUS_USE_OPAQUE_LINE;
405 if ( compl ) Arc( ps, ELLIPSE_RECT, ARC_COMPLETE);
406 gp_Chord( self, ELLIPSE_RECT, ARC_ANGLED, angleStart, angleEnd, false);
407 STYLUS_RESTORE_OPAQUE_LINE;
408 }
409
410 STYLUS_USE_PEN( ps);
411 while( compl--)
412 Arc( ps, ELLIPSE_RECT, ARC_COMPLETE);
413 if ( needf) {
414 if ( !( ok = gp_Chord( self, ELLIPSE_RECT, ARC_ANGLED, angleStart, angleEnd, false))) apiErr;
415 }
416 SelectObject( ps, old);
417 return ok;
418 }}
419
420 Bool
apc_gp_draw_poly(Handle self,int numPts,Point * points)421 apc_gp_draw_poly( Handle self, int numPts, Point * points)
422 {objCheck false;{
423 int i;
424 POINT *p;
425 Bool ok;
426
427 if ((p = malloc( sizeof(POINT) * numPts)) == NULL)
428 return false;
429
430 for ( i = 0; i < numPts; i++) {
431 p[i].x = SHIFT_X(points[i].x);
432 p[i].y = SHIFT_Y(points[i].y);
433 }
434 if ( p[0]. x != p[numPts - 1].x || p[0]. y != p[numPts - 1].y || numPts == 2)
435 adjust_line_end_LONG( p[numPts - 2].x, p[numPts - 2].y, &p[numPts - 1].x, &p[numPts - 1].y);
436
437 if (EMULATE_OPAQUE_LINE) {
438 STYLUS_USE_OPAQUE_LINE;
439 Polyline( sys ps, p, numPts);
440 STYLUS_RESTORE_OPAQUE_LINE;
441 }
442
443 STYLUS_USE_PEN( sys ps);
444 if ( !(ok = Polyline( sys ps, p, numPts))) apiErr;
445
446 free(p);
447
448 return ok;
449 }}
450
451 Bool
apc_gp_draw_poly2(Handle self,int numPts,Point * points)452 apc_gp_draw_poly2( Handle self, int numPts, Point * points)
453 {objCheck false;{
454 Bool ok = true;
455 int i;
456 DWORD * pts;
457 POINT * p;
458
459 pts = ( DWORD *) malloc( sizeof( DWORD) * numPts);
460 if ( !pts) return false;
461 p = malloc( sizeof(POINT) * numPts);
462 if ( !p ) {
463 free(pts);
464 return false;
465 }
466
467 for ( i = 0; i < numPts; i++) {
468 p[i].x = SHIFT_X(points[i].x);
469 p[i].y = SHIFT_Y(points[i].y);
470 pts[i] = 2;
471 if ( i & 1)
472 adjust_line_end_LONG( p[i - 1].x, p[i - 1].y, &p[i].x, &p[i].y);
473 }
474
475 if (EMULATE_OPAQUE_LINE) {
476 STYLUS_USE_OPAQUE_LINE;
477 PolyPolyline( sys ps, p, pts, numPts/2);
478 STYLUS_RESTORE_OPAQUE_LINE;
479 }
480
481 STYLUS_USE_PEN( sys ps);
482 if ( !( ok = PolyPolyline( sys ps, p, pts, numPts/2))) apiErr;
483 free( pts);
484 free( p);
485 return ok;
486 }}
487
488 Bool
apc_gp_ellipse(Handle self,int x,int y,int dX,int dY)489 apc_gp_ellipse( Handle self, int x, int y, int dX, int dY)
490 {objCheck false;{
491 Bool ok = true;
492 HDC ps = sys ps;
493 HGDIOBJ old = SelectObject( ps, hBrushHollow);
494
495 SHIFT_XY(x,y);
496
497 if (EMULATE_OPAQUE_LINE) {
498 STYLUS_USE_OPAQUE_LINE;
499 Ellipse( ps, ELLIPSE_RECT);
500 STYLUS_RESTORE_OPAQUE_LINE;
501 }
502
503 STYLUS_USE_PEN( ps);
504 if ( !( ok = Ellipse( ps, ELLIPSE_RECT))) apiErr;
505 SelectObject( ps, old);
506 return ok;
507 }}
508
509 Bool
apc_gp_fill_chord(Handle self,int x,int y,int dX,int dY,double angleStart,double angleEnd)510 apc_gp_fill_chord( Handle self, int x, int y, int dX, int dY, double angleStart, double angleEnd)
511 {objCheck false;{
512 Bool ok = true;
513 HDC ps = sys ps;
514 HGDIOBJ old;
515 Bool comp;
516 int compl, needf;
517
518 compl = arc_completion( &angleStart, &angleEnd, &needf);
519 comp = ((sys psFillMode & fmOverlay) == 0) || stylus_complex( &sys stylus, ps);
520 SHIFT_XY(x,y);
521 STYLUS_USE_BRUSH( ps);
522
523 if ( comp) {
524 old = SelectObject( ps, hPenHollow);
525 while ( compl--)
526 if ( !( ok = Ellipse( ps, ELLIPSE_RECT_SUPERINCLUSIVE))) apiErr;
527 if ( !( ok = !needf || gp_Chord(
528 self, ELLIPSE_RECT_SUPERINCLUSIVE, ARC_ANGLED_SUPERINCLUSIVE, angleStart, angleEnd, true
529 ))) apiErr;
530 } else {
531 old = SelectObject( ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
532 while ( compl--)
533 if ( !( ok = Ellipse( ps, ELLIPSE_RECT))) apiErr;
534 if ( !( ok = !needf || gp_Chord(
535 self, ELLIPSE_RECT, ARC_ANGLED_SUPERINCLUSIVE, angleStart, angleEnd, true
536 ))) apiErr;
537 }
538 old = SelectObject( ps, old);
539 if ( !comp) DeleteObject( old);
540 return ok;
541 }}
542
543 Bool
apc_gp_fill_ellipse(Handle self,int x,int y,int dX,int dY)544 apc_gp_fill_ellipse( Handle self, int x, int y, int dX, int dY)
545 {objCheck false;{
546 Bool ok = true;
547 HDC ps = sys ps;
548 HGDIOBJ old;
549 Bool comp = ((sys psFillMode & fmOverlay) == 0) || stylus_complex( &sys stylus, ps);
550 STYLUS_USE_BRUSH( ps);
551 SHIFT_XY(x,y);
552 if ( comp) {
553 old = SelectObject( ps, hPenHollow);
554 if ( !( ok = Ellipse( ps, ELLIPSE_RECT_SUPERINCLUSIVE))) apiErr;
555 } else {
556 old = SelectObject( ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
557 if ( !( ok = Ellipse( ps, ELLIPSE_RECT))) apiErr;
558 }
559 old = SelectObject( ps, old);
560 if ( !comp) DeleteObject( old);
561 return ok;
562 }}
563
564 static Handle ctx_R22R4[] = {
565 R2_COPYPEN , SRCCOPY ,
566 R2_XORPEN , SRCINVERT ,
567 R2_MASKPEN , SRCAND ,
568 R2_MERGEPEN , SRCPAINT ,
569 R2_NOTCOPYPEN , NOTSRCCOPY ,
570 R2_MASKPENNOT , SRCERASE ,
571 R2_MERGEPENNOT , 0x00DD0228 ,
572 R2_MASKNOTPEN , 0x00220326 ,
573 R2_MERGENOTPEN , MERGEPAINT ,
574 R2_NOTXORPEN , 0x00990066 ,
575 R2_NOTMASKPEN , 0x007700E6 ,
576 R2_NOTMERGEPEN , NOTSRCERASE ,
577 R2_NOP , 0x00AA0029 ,
578 R2_BLACK , BLACKNESS ,
579 R2_WHITE , WHITENESS ,
580 R2_NOT , DSTINVERT ,
581 endCtx
582 };
583
584 Bool
apc_gp_fill_poly(Handle self,int numPts,Point * points)585 apc_gp_fill_poly( Handle self, int numPts, Point * points)
586 {Bool ok = true; objCheck false;{
587 HDC ps = sys ps;
588 int i;
589 POINT *p;
590
591 if ((p = malloc( sizeof(POINT) * numPts)) == NULL)
592 return false;
593
594 for ( i = 0; i < numPts; i++) {
595 p[i].x = SHIFT_X(points[i].x);
596 p[i].y = SHIFT_Y(points[i].y);
597 }
598 if ( numPts == 2 )
599 adjust_line_end_LONG( p[0].x, p[0].y, &p[1].x, &p[1].y);
600
601 if (( sys psFillMode & fmOverlay) == 0) {
602 HGDIOBJ old = SelectObject( ps, hPenHollow);
603 STYLUS_USE_BRUSH( ps);
604 if ( !( ok = Polygon( ps, p, numPts))) apiErr;
605 SelectObject( ps, old);
606 } else if ( !stylus_complex( &sys stylus, ps)) {
607 HPEN old = SelectObject( ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
608 STYLUS_USE_BRUSH( ps);
609 if ( !( ok = Polygon( ps, p, numPts))) apiErr;
610 DeleteObject( SelectObject( ps, old));
611 } else {
612 int dx = sys lastSize.x;
613 int dy = sys lastSize.y;
614 int rop = ctx_remap_def( GetROP2( ps), ctx_R22R4, true, SRCCOPY);
615 Point bound = {0,0};
616 Point trans;
617 HBITMAP bmMask, bmSrc, bmJ;
618 HDC dc;
619 HGDIOBJ old1, oldelta;
620 Bool db = is_apt( aptDeviceBitmap) || is_apt( aptBitmap);
621 trans. x = dx;
622 trans. y = dy;
623 for ( i = 0; i < numPts; i++) {
624 if ( p[i].x > bound.x) bound.x = p[i].x;
625 if ( p[i].y > bound.y) bound.y = p[i].y;
626 if ( p[i].x < trans.x) trans.x = p[i].x;
627 if ( p[i].y < trans.y) trans.y = p[i].y;
628 }
629 if (( trans. x == dx) || ( trans. y == dy)) {
630 free(p);
631 return false;
632 }
633 if ( bound. x > dx) bound. x = dx;
634 if ( bound. y > dy) bound. y = dy;
635 for ( i = 0; i < numPts; i++) {
636 p[i].x -= trans.x;
637 p[i].y -= trans.y;
638 }
639 bound.x -= trans.x - 1;
640 bound.y -= trans.y - 1;
641
642 if ( !( dc = dc_compat_alloc( ps))) apiErrRet;
643 if ( db) {
644 if ( !( ps = dc_alloc())) { // fact that if dest ps is memory dc, CCB will result mono-bitmap
645 dc_compat_free();
646 free(p);
647 return false;
648 }
649 }
650 if ( !( bmSrc = CreateCompatibleBitmap( ps, bound. x, bound. y))) {
651 apiErr;
652 if ( db) dc_free();
653 dc_compat_free();
654 free(p);
655 return false;
656 }
657 if ( db) {
658 dc_free();
659 ps = sys ps;
660 }
661 if ( !( bmMask = CreateBitmap( bound. x, bound. y, 1, 1, NULL))) {
662 apiErr;
663 dc_compat_free();
664 free(p);
665 return false;
666 }
667 bmJ = SelectObject( dc, bmSrc);
668 old1 = SelectObject( dc, sys stylusResource-> hbrush);
669 oldelta = SelectObject( dc, hPenHollow);
670 Rectangle( dc, 0, 0, bound. x + 1, bound. y + 1);
671 SelectObject( dc, oldelta);
672 SelectObject( dc, old1);
673 SelectObject( dc, bmMask);
674 SetROP2( dc, R2_WHITE);
675 Rectangle( dc, 0, 0, bound. x, bound. y);
676 SetROP2( dc, R2_BLACK);
677 if ( !( ok = Polygon( dc, p, numPts))) apiErr;
678 SelectObject( dc, bmSrc);
679 if ( !( ok &= MaskBlt( ps, trans. x, trans. y, bound. x, bound. y, dc, 0, 0, bmMask, 0, 0,
680 MAKEROP4( 0x00AA0029, rop)))) apiErr;
681 SelectObject( dc, bmJ);
682 dc_compat_free();
683 DeleteObject( bmMask);
684 DeleteObject( bmSrc);
685 }
686 free(p);
687 }return ok;}
688
689 Bool
apc_gp_fill_sector(Handle self,int x,int y,int dX,int dY,double angleStart,double angleEnd)690 apc_gp_fill_sector( Handle self, int x, int y, int dX, int dY, double angleStart, double angleEnd)
691 {objCheck false;{
692 Bool ok = true;
693 HDC ps = sys ps;
694 HGDIOBJ old;
695 POINT pts[ 3];
696 Bool comp;
697 int compl, needf;
698
699 compl = arc_completion( &angleStart, &angleEnd, &needf);
700 comp = ((sys psFillMode & fmOverlay) == 0) || stylus_complex( &sys stylus, ps);
701
702 SHIFT_XY(x,y);
703 pts[0].x = x + cos( angleEnd / GRAD) * dX / 2 + 0.5;
704 pts[0].y = y - sin( angleEnd / GRAD) * dY / 2 + 0.5;
705 pts[1].x = x + cos( angleStart / GRAD) * dX / 2 + 0.5;
706 pts[1].y = y - sin( angleStart / GRAD) * dY / 2 + 0.5;
707
708 STYLUS_USE_BRUSH( ps);
709 if ( comp) {
710 old = SelectObject( ps, hPenHollow);
711 while ( compl--)
712 if ( !( ok = Ellipse( ps, ELLIPSE_RECT_SUPERINCLUSIVE))) apiErr;
713 if ( !( ok = !needf || gp_Pie(
714 self, ELLIPSE_RECT_SUPERINCLUSIVE,
715 pts[1].x, pts[1].y,
716 pts[0].x, pts[0].y,
717 angleStart, angleEnd, true
718 ))) apiErr;
719 } else {
720 old = SelectObject( ps, CreatePen( PS_SOLID, 1, sys stylus. brush. lb. lbColor));
721 while ( compl--)
722 if ( !( ok = Ellipse( ps, ELLIPSE_RECT))) apiErr;
723 if ( !( ok = !needf || gp_Pie(
724 self, ELLIPSE_RECT,
725 pts[ 1]. x, pts[ 1]. y,
726 pts[ 0]. x, pts[ 0]. y,
727 angleStart, angleEnd, true
728 ))) apiErr;
729 }
730 old = SelectObject( ps, old);
731 if ( !comp) DeleteObject( old);
732 return ok;
733 }}
734
735 Bool
apc_gp_flood_fill(Handle self,int x,int y,Color borderColor,Bool singleBorder)736 apc_gp_flood_fill( Handle self, int x, int y, Color borderColor, Bool singleBorder)
737 {objCheck false;{
738 HDC ps = sys ps;
739 STYLUS_USE_BRUSH( ps);
740 SHIFT_XY(x,y);
741 if ( !ExtFloodFill( ps, x, y, remap_color( borderColor, true),
742 singleBorder ? FLOODFILLSURFACE : FLOODFILLBORDER)) apiErrRet;
743 return true;
744 }}
745
746 Color
apc_gp_get_pixel(Handle self,int x,int y)747 apc_gp_get_pixel( Handle self, int x, int y)
748 {objCheck clInvalid;{
749 COLORREF c;
750 SHIFT_XY(x,y);
751 c = GetPixel( sys ps, x, y);
752 if ( c == CLR_INVALID) return clInvalid;
753 return remap_color(( Color) c, false);
754 }}
755
756 ApiHandle
apc_gp_get_handle(Handle self)757 apc_gp_get_handle( Handle self)
758 {
759 objCheck 0;
760 return ( ApiHandle) sys ps;
761 }
762
763
764 Bool
apc_gp_line(Handle self,int x1,int y1,int x2,int y2)765 apc_gp_line( Handle self, int x1, int y1, int x2, int y2)
766 {objCheck false;{
767 HDC ps = sys ps;
768
769 adjust_line_end_int( x1, y1, &x2, &y2);
770 SHIFT_XY(x1,y1);
771 SHIFT_XY(x2,y2);
772
773 if (EMULATE_OPAQUE_LINE) {
774 STYLUS_USE_OPAQUE_LINE;
775 MoveToEx( ps, x1, y1, NULL);
776 LineTo( ps, x2, y2);
777 STYLUS_RESTORE_OPAQUE_LINE;
778 }
779
780 STYLUS_USE_PEN( ps);
781
782 MoveToEx( ps, x1, y1, NULL);
783 if ( !LineTo( ps, x2, y2)) apiErrRet;
784
785 return true;
786 }}
787
788 Bool
apc_gp_put_image(Handle self,Handle image,int x,int y,int xFrom,int yFrom,int xLen,int yLen,int rop)789 apc_gp_put_image( Handle self, Handle image, int x, int y, int xFrom, int yFrom, int xLen, int yLen, int rop)
790 {
791 return apc_gp_stretch_image ( self, image, x, y, xFrom, yFrom, xLen, yLen, xLen, yLen, rop);
792 }
793
794 Bool
apc_gp_rectangle(Handle self,int x1,int y1,int x2,int y2)795 apc_gp_rectangle( Handle self, int x1, int y1, int x2, int y2)
796 {objCheck false;{
797 Bool ok = true;
798 HDC ps = sys ps;
799 HGDIOBJ old;
800
801 check_swap( x1, x2);
802 check_swap( y1, y2);
803
804 old = SelectObject( ps, hBrushHollow);
805 if ( sys stylus. pen. lopnWidth. x > 1 &&
806 (sys stylus. pen. lopnWidth. x % 2) == 0
807 ) {
808 /* change up-winding to down-winding */
809 y1--;
810 y2--;
811 }
812 SHIFT_XY(x1,y1);
813 SHIFT_XY(x2,y2);
814
815 if ( EMULATE_OPAQUE_LINE ) {
816 STYLUS_USE_OPAQUE_LINE;
817 Rectangle( sys ps, x1, y1 + 1, x2 + 1, y2);
818 STYLUS_RESTORE_OPAQUE_LINE;
819 }
820
821 STYLUS_USE_PEN( ps);
822 if ( !( ok = Rectangle( sys ps, x1, y1 + 1, x2 + 1, y2))) apiErr;
823 SelectObject( ps, old);
824 return ok;
825 }}
826
827 Bool
apc_gp_sector(Handle self,int x,int y,int dX,int dY,double angleStart,double angleEnd)828 apc_gp_sector( Handle self, int x, int y, int dX, int dY, double angleStart, double angleEnd)
829 {objCheck false;{
830 Bool ok = true;
831 HDC ps = sys ps;
832 int compl, needf;
833 POINT pts[ 2];
834 HGDIOBJ old;
835
836 compl = arc_completion( &angleStart, &angleEnd, &needf);
837 old = SelectObject( ps, hBrushHollow);
838
839 pts[0].x = x + cos(angleEnd / GRAD) * dX / 2 + 0.5;
840 pts[0].y = y - sin(angleEnd / GRAD) * dY / 2 + 0.5;
841 pts[1].x = x + cos(angleStart / GRAD) * dX / 2 + 0.5;
842 pts[1].y = y - sin(angleStart / GRAD) * dY / 2 + 0.5;
843
844 SHIFT_XY(x,y);
845
846 if (EMULATE_OPAQUE_LINE) {
847 STYLUS_USE_OPAQUE_LINE;
848 if ( compl ) Arc( ps, ELLIPSE_RECT, ARC_COMPLETE);
849 gp_Pie(
850 self, ELLIPSE_RECT,
851 pts[1].x, pts[1].y,
852 pts[0].x, pts[0].y,
853 angleStart, angleEnd, false
854 );
855 STYLUS_RESTORE_OPAQUE_LINE;
856 }
857
858 STYLUS_USE_PEN( ps);
859
860 while( compl--)
861 Arc( ps, ELLIPSE_RECT, ARC_COMPLETE);
862 if ( needf) {
863 if ( !( ok = gp_Pie(
864 self, ELLIPSE_RECT,
865 pts[1].x, pts[1].y,
866 pts[0].x, pts[0].y,
867 angleStart, angleEnd, false
868 ))) apiErr;
869 }
870
871 SelectObject( ps, old);
872 return ok;
873 }}
874
875 Bool
apc_gp_set_pixel(Handle self,int x,int y,Color color)876 apc_gp_set_pixel( Handle self, int x, int y, Color color)
877 {
878 objCheck false;
879 SHIFT_XY(x,y);
880 SetPixelV( sys ps, x, y, remap_color( color, true));
881 return true;
882 }
883
884 // gpi settings
885 Color
apc_gp_get_back_color(Handle self)886 apc_gp_get_back_color( Handle self)
887 {
888 objCheck 0;
889 return remap_color( sys lbs[1], false);
890 }
891
892 int
apc_gp_get_bpp(Handle self)893 apc_gp_get_bpp( Handle self)
894 {
895 objCheck 0;
896 return sys bpp;
897 }
898
899 Color
apc_gp_get_color(Handle self)900 apc_gp_get_color( Handle self)
901 {
902 objCheck 0;
903 return remap_color( sys ps ? sys stylus. pen. lopnColor : sys lbs[0], false);
904 }
905
906 int
apc_gp_get_fill_mode(Handle self)907 apc_gp_get_fill_mode( Handle self)
908 {
909 objCheck 0;
910 return sys ps ? sys psFillMode : sys fillMode;
911 }
912
913 static Handle ctx_le2PS_ENDCAP[] = {
914 leRound, PS_ENDCAP_ROUND ,
915 leSquare, PS_ENDCAP_SQUARE ,
916 leFlat, PS_ENDCAP_FLAT ,
917 endCtx
918 };
919
920 int
apc_gp_get_line_end(Handle self)921 apc_gp_get_line_end( Handle self)
922 {
923 objCheck 0;
924 if ( !sys ps) return sys lineEnd;
925 return ctx_remap_def( sys stylus. extPen. lineEnd, ctx_le2PS_ENDCAP, false, leRound);
926 }
927
928 static Handle ctx_lj2PS_JOIN[] = {
929 ljRound, PS_JOIN_ROUND ,
930 ljBevel, PS_JOIN_BEVEL ,
931 ljMiter, PS_JOIN_MITER ,
932 endCtx
933 };
934
935 int
apc_gp_get_line_join(Handle self)936 apc_gp_get_line_join( Handle self)
937 {
938 objCheck 0;
939 if ( !sys ps) return sys lineJoin;
940 return ctx_remap_def( sys stylus. extPen. lineJoin, ctx_lj2PS_JOIN, false, ljRound);
941 }
942
943 float
apc_gp_get_line_width(Handle self)944 apc_gp_get_line_width( Handle self)
945 {
946 objCheck 0;
947 return sys ps ? sys stylus.extPen.lineWidth : sys lineWidth;
948 }
949
950 int
apc_gp_get_line_pattern(Handle self,unsigned char * buffer)951 apc_gp_get_line_pattern( Handle self, unsigned char * buffer)
952 {
953 objCheck 0;
954 if ( !sys ps) {
955 memcpy(
956 ( char *) buffer,
957 (char*)(( sys linePatternLen > sizeof(sys linePattern)) ? sys linePattern : (Byte*)(&sys linePattern)),
958 sys linePatternLen
959 );
960 return sys linePatternLen;
961 }
962
963 switch ( sys stylus. pen. lopnStyle) {
964 case PS_NULL:
965 strcpy(( char *) buffer, "");
966 return 0;
967 case PS_DASH:
968 strcpy(( char *) buffer, psDash);
969 return 2;
970 case PS_DOT:
971 strcpy(( char *) buffer, psDot);
972 return 2;
973 case PS_DASHDOT:
974 strcpy(( char *) buffer, psDashDot);
975 return 4;
976 case PS_DASHDOTDOT:
977 strcpy(( char *) buffer, psDashDotDot);
978 return 6;
979 case PS_USERSTYLE:
980 {
981 int i;
982 int len = sys stylus. extPen. patResource-> dotsCount;
983 if ( len > 255) len = 255;
984 for ( i = 0; i < len; i++)
985 buffer[ i] = sys stylus. extPen. patResource-> dots[ i];
986 return len;
987 }
988 default:
989 strcpy(( char *) buffer, "\1");
990 return 1;
991 }
992 }
993
994 float
apc_gp_get_miter_limit(Handle self)995 apc_gp_get_miter_limit( Handle self)
996 {
997 FLOAT ml;
998 objCheck 0;
999 if ( !sys ps) return sys miterLimit;
1000 if (! GetMiterLimit( sys ps, &ml)) return 0;
1001 return (float)ml;
1002 }
1003
1004 Color
apc_gp_get_nearest_color(Handle self,Color color)1005 apc_gp_get_nearest_color( Handle self, Color color)
1006 {
1007 #define quit return remap_color( GetNearestColor( sys ps, clr), false)
1008
1009 XLOGPALETTE lpLoc, lpGlob;
1010 int locIdx, globIdx, cdiff;
1011 long clrGlob, clr = remap_color( color, true);
1012 objCheck 0;
1013
1014 if ( !sys pal || ( sys bpp > 8)) quit;
1015 lpLoc. palNumEntries = GetPaletteEntries( sys pal, 0, 256, lpLoc. palPalEntry);
1016 if ( lpLoc. palNumEntries == 0) quit;
1017 lpGlob. palNumEntries = GetSystemPaletteEntries( sys ps, 0, 256, lpGlob. palPalEntry);
1018 if ( lpGlob. palNumEntries == 0) quit;
1019
1020 locIdx = palette_match_color( &lpLoc, clr, &cdiff);
1021 if ( cdiff >= COLOR_TOLERANCE) quit;
1022
1023 clrGlob = ARGB(
1024 lpLoc. palPalEntry[ locIdx]. peBlue,
1025 lpLoc. palPalEntry[ locIdx]. peGreen,
1026 lpLoc. palPalEntry[ locIdx]. peRed
1027 );
1028 globIdx = palette_match_color( &lpGlob, clrGlob, &cdiff);
1029 if ( cdiff >= COLOR_TOLERANCE) quit;
1030 return ARGB(
1031 lpGlob. palPalEntry[ globIdx]. peRed,
1032 lpGlob. palPalEntry[ globIdx]. peGreen,
1033 lpGlob. palPalEntry[ globIdx]. peBlue
1034 );
1035 #undef quit
1036 }
1037
1038 PRGBColor
apc_gp_get_physical_palette(Handle self,int * color)1039 apc_gp_get_physical_palette( Handle self, int * color)
1040 {
1041 XLOGPALETTE lpGlob;
1042 int i, nCol;
1043 PRGBColor r;
1044
1045 *color = 0;
1046 objCheck NULL;
1047
1048 if (( GetDeviceCaps( sys ps, RASTERCAPS) & RC_PALETTE) == 0)
1049 return NULL;
1050
1051 nCol = GetDeviceCaps( sys ps, NUMCOLORS);
1052 if ( nCol <= 0 || nCol > 256)
1053 return NULL;
1054
1055
1056 if ( sys pal && ( nCol > 16)) {
1057 XLOGPALETTE lp;
1058 int i, lpCount = 0;
1059 int map[ 256];
1060
1061 lp. palNumEntries = GetPaletteEntries( sys pal, 0, 256, lp. palPalEntry);
1062 lpGlob. palNumEntries = GetSystemPaletteEntries( sys ps, 0, 256, lpGlob. palPalEntry);
1063
1064 for ( i = 0; i < lp. palNumEntries; i++) {
1065 long clr = ARGB(
1066 lp. palPalEntry[ i]. peBlue,
1067 lp. palPalEntry[ i]. peGreen,
1068 lp. palPalEntry[ i]. peRed
1069 );
1070 int j, cdiff;
1071 int idx = palette_match_color( &lpGlob, clr, &cdiff);
1072 Bool hasmatch = 0;
1073
1074 if ( cdiff >= COLOR_TOLERANCE) continue;
1075
1076 if ( idx < 10 || idx > 245) continue;
1077
1078 for ( j = 0; j < lpCount; j++)
1079 if ( map[ j] == idx) {
1080 hasmatch = 1;
1081 break;
1082 }
1083 if ( hasmatch) continue;
1084 map[ lpCount++] = idx;
1085 }
1086
1087 for ( i = 0; i < lpCount; i++)
1088 lp. palPalEntry[ i] = lpGlob. palPalEntry[ map[ i]];
1089 for ( i = 0; i < lpCount; i++)
1090 lpGlob. palPalEntry[ i + nCol] = lp. palPalEntry[ i];
1091 *color = nCol + lpCount;
1092 } else {
1093 *color = GetSystemPaletteEntries( sys ps, 0, 256, lpGlob. palPalEntry);
1094 if (( nCol == 20) && ( *color == 256))
1095 *color = 20;
1096 }
1097
1098 if ( nCol == 20) {
1099 int i;
1100 for ( i = 0; i < 10; i++)
1101 lpGlob. palPalEntry[ i + 10] = lpGlob. palPalEntry[ 255 - i];
1102 }
1103
1104 r = ( PRGBColor) malloc( sizeof( RGBColor) * *color);
1105 if ( !r) return NULL;
1106
1107 for ( i = 0; i < *color; i++) {
1108 r[i].r = lpGlob. palPalEntry[i]. peRed;
1109 r[i].g = lpGlob. palPalEntry[i]. peGreen;
1110 r[i].b = lpGlob. palPalEntry[i]. peBlue;
1111 }
1112 return r;
1113 }
1114
1115 Point
apc_gp_get_resolution(Handle self)1116 apc_gp_get_resolution( Handle self)
1117 {
1118 Point p = guts. displayResolution;
1119 if ( !self) return p;
1120 objCheck p;
1121 return is_apt( aptPrinter ) ? sys res : p;
1122 }
1123
1124 static Handle ctx_rop2R2[] = {
1125 ropCopyPut , R2_COPYPEN ,
1126 ropXorPut , R2_XORPEN ,
1127 ropAndPut , R2_MASKPEN ,
1128 ropOrPut , R2_MERGEPEN ,
1129 ropNotPut , R2_NOTCOPYPEN ,
1130 ropNotDestAnd , R2_MASKPENNOT ,
1131 ropNotDestOr , R2_MERGEPENNOT ,
1132 ropNotSrcAnd , R2_MASKNOTPEN ,
1133 ropNotSrcOr , R2_MERGENOTPEN ,
1134 ropNotXor , R2_NOTXORPEN ,
1135 ropNotAnd , R2_NOTMASKPEN ,
1136 ropNotOr , R2_NOTMERGEPEN ,
1137 ropNoOper , R2_NOP ,
1138 ropBlackness , R2_BLACK ,
1139 ropWhiteness , R2_WHITE ,
1140 ropInvert , R2_NOT ,
1141 endCtx
1142 };
1143
1144
1145 int
apc_gp_get_rop(Handle self)1146 apc_gp_get_rop( Handle self)
1147 {
1148 objCheck 0;
1149 if ( !sys ps) return sys rop;
1150 return ctx_remap_def( GetROP2( sys ps), ctx_rop2R2, false, ropCopyPut);
1151 }
1152
1153 int
apc_gp_get_rop2(Handle self)1154 apc_gp_get_rop2( Handle self)
1155 {
1156 objCheck 0;
1157 if ( !sys ps) return sys rop2;
1158 return ( GetBkMode( sys ps) == OPAQUE) ? ropCopyPut : ropNoOper;
1159 }
1160
1161 Point
apc_gp_get_transform(Handle self)1162 apc_gp_get_transform( Handle self)
1163 {
1164 Point p = {0,0};
1165 objCheck p;
1166 if ( !sys ps) return sys transform;
1167 p = sys gp_transform;
1168 p. y = -p. y;
1169 p. x += sys transform2. x;
1170 p. y -= sys transform2. y;
1171 return p;
1172 }
1173
1174 #define pal_ok ((sys bpp <= 8) && ( sys pal))
1175
1176 Bool
apc_gp_set_back_color(Handle self,Color color)1177 apc_gp_set_back_color( Handle self, Color color)
1178 {
1179 long clr = remap_color( color, true);
1180 objCheck false;
1181 if ( sys ps) {
1182 PStylus s = & sys stylus;
1183 if ( pal_ok) clr = palette_match( self, clr);
1184 if ( SetBkColor( sys ps, clr) == CLR_INVALID) apiErr;
1185 s-> brush. backColor = clr;
1186 if ( s-> brush. lb. lbStyle == BS_DIBPATTERNPT)
1187 stylus_change( self);
1188 if ( sys opaquePen ) {
1189 sys stylusFlags &=~ stbPen;
1190 SelectObject( sys ps, sys stockPen);
1191 DeleteObject( sys opaquePen );
1192 sys opaquePen = NULL;
1193 }
1194 }
1195 sys lbs[1] = clr;
1196 return true;
1197 }
1198
1199 Bool
apc_gp_set_color(Handle self,Color color)1200 apc_gp_set_color( Handle self, Color color)
1201 {
1202 long clr = remap_color( color, true);
1203 objCheck false;
1204 sys lbs[0] = clr;
1205 if ( sys ps) {
1206 PStylus s = & sys stylus;
1207 if ( pal_ok) clr = palette_match( self, clr);
1208 s-> pen. lopnColor = ( COLORREF) clr;
1209 if ( s-> brush. lb. lbStyle != BS_DIBPATTERNPT)
1210 s-> brush. lb. lbColor = ( COLORREF) clr;
1211 stylus_change( self);
1212 if ( sys alphaArenaPalette ) {
1213 free(sys alphaArenaPalette);
1214 sys alphaArenaPalette = NULL;
1215 }
1216 }
1217 return true;
1218 }
1219
1220 Bool
apc_gp_set_fill_mode(Handle self,int fillMode)1221 apc_gp_set_fill_mode( Handle self, int fillMode)
1222 {
1223 objCheck false;
1224 if ( sys ps) {
1225 SetPolyFillMode( sys ps, ((fillMode & fmWinding) == fmAlternate) ? ALTERNATE : WINDING);
1226 sys psFillMode = fillMode;
1227 } else
1228 sys fillMode = fillMode;
1229 return true;
1230 }
1231
1232 Bool
apc_gp_set_fill_pattern(Handle self,FillPattern pattern)1233 apc_gp_set_fill_pattern( Handle self, FillPattern pattern)
1234 {
1235 objCheck false;
1236 {
1237 HDC ps = sys ps;
1238 PStylus s = & sys stylus;
1239 uint32_t *p1 = ( uint32_t*) pattern;
1240 uint32_t *p2 = p1 + 1;
1241 if ( !ps) {
1242 memcpy( &sys fillPattern2, pattern, sizeof( FillPattern));
1243 return true;
1244 }
1245 memcpy( &sys fillPattern, pattern, sizeof( FillPattern));
1246 if (( *p1 == 0) && ( *p2 == 0)) {
1247 s-> brush. lb. lbStyle = BS_SOLID;
1248 s-> brush. lb. lbColor = GetBkColor( ps);
1249 s-> brush. lb. lbHatch = 0;
1250 s-> brush. backColor = 0;
1251 memset( s-> brush. pattern, 0, sizeof( s-> brush. pattern));
1252 } else if (( *p1 == 0xFFFFFFFF) && ( *p2 == 0xFFFFFFFF)) {
1253 s-> brush. lb. lbStyle = BS_SOLID;
1254 s-> brush. lb. lbColor = s-> pen. lopnColor;
1255 s-> brush. lb. lbHatch = 0;
1256 s-> brush. backColor = 0;
1257 memset( s-> brush. pattern, 0, sizeof( s-> brush. pattern));
1258 } else {
1259 s-> brush. lb. lbStyle = BS_DIBPATTERNPT;
1260 s-> brush. lb. lbColor = DIB_RGB_COLORS;
1261 s-> brush. lb. lbHatch = ( LONG_PTR) &bmiHatch;
1262 s-> brush. backColor = GetBkColor( ps);
1263 memcpy( s-> brush. pattern, pattern, sizeof( FillPattern));
1264 }
1265 stylus_change( self);
1266 return true;
1267 }}
1268
1269 Bool
apc_gp_set_fill_pattern_offset(Handle self,Point offset)1270 apc_gp_set_fill_pattern_offset( Handle self, Point offset)
1271 {
1272 objCheck false;
1273 if ( sys ps)
1274 SetBrushOrgEx( sys ps, offset.x, 8 - offset.y, NULL);
1275 else
1276 sys fillPatternOffset = offset;
1277 return true;
1278 }
1279
1280 Bool
apc_gp_set_font(Handle self,PFont font)1281 apc_gp_set_font( Handle self, PFont font)
1282 {
1283 OUTLINETEXTMETRICW otm;
1284 objCheck false;
1285 if ( !sys ps) return true;
1286 font_change( self, font);
1287
1288 if ( GetOutlineTextMetricsW(sys ps, sizeof(otm), &otm)) {
1289 sys tmOverhang = otm.otmTextMetrics.tmOverhang;
1290 sys tmPitchAndFamily = otm.otmTextMetrics.tmPitchAndFamily;
1291 sys otmsStrikeoutSize = otm.otmsStrikeoutSize;
1292 sys otmsStrikeoutPosition = otm.otmsStrikeoutPosition;
1293 sys otmsUnderscoreSize = otm.otmsUnderscoreSize;
1294 sys otmsUnderscorePosition = otm.otmsUnderscorePosition;
1295 } else {
1296 TEXTMETRICW tm;
1297 GetTextMetricsW( sys ps, &tm);
1298 sys tmOverhang = tm.tmOverhang;
1299 sys tmPitchAndFamily = tm.tmPitchAndFamily;
1300 sys otmsStrikeoutSize = sys otmsStrikeoutPosition = sys otmsUnderscoreSize = sys otmsUnderscorePosition = -1;
1301 }
1302
1303 sys font_sin = sys font_cos = 0.0;
1304
1305 return true;
1306 }
1307
1308 FillPattern *
apc_gp_get_fill_pattern(Handle self)1309 apc_gp_get_fill_pattern( Handle self)
1310 {
1311 objCheck NULL;
1312 return sys ps ? &sys fillPattern : &sys fillPattern2;
1313 }
1314
1315 Point
apc_gp_get_fill_pattern_offset(Handle self)1316 apc_gp_get_fill_pattern_offset( Handle self)
1317 {
1318 Point p = {0,0};
1319 POINT wp;
1320 objCheck p;
1321 if ( !sys ps)
1322 return sys fillPatternOffset;
1323 GetBrushOrgEx( sys ps, &wp);
1324 p. x = wp. x;
1325 p. y = 8 - wp. y;
1326 return p;
1327 }
1328
1329 Bool
apc_gp_set_line_end(Handle self,int lineEnd)1330 apc_gp_set_line_end( Handle self, int lineEnd)
1331 {
1332 objCheck false;
1333 if ( !sys ps) {
1334 sys lineEnd = lineEnd;
1335 } else {
1336 PStylus s = &sys stylus;
1337 PEXTPEN ep = &s-> extPen;
1338 ep-> lineEnd = ctx_remap_def( lineEnd, ctx_le2PS_ENDCAP, true, PS_ENDCAP_ROUND);
1339 if (( ep-> actual = stylus_extpenned( s)))
1340 ep-> style = stylus_get_extpen_style( s);
1341 stylus_change( self);
1342 }
1343 return true;
1344 }
1345
1346 Bool
apc_gp_set_line_join(Handle self,int lineJoin)1347 apc_gp_set_line_join( Handle self, int lineJoin)
1348 {
1349 objCheck false;
1350 if ( !sys ps) {
1351 sys lineJoin = lineJoin;
1352 } else {
1353 PStylus s = &sys stylus;
1354 PEXTPEN ep = &s-> extPen;
1355 ep-> lineJoin = ctx_remap_def( lineJoin, ctx_lj2PS_JOIN, true, PS_JOIN_ROUND);
1356 if (( ep-> actual = stylus_extpenned( s)))
1357 ep-> style = stylus_get_extpen_style( s);
1358 stylus_change( self);
1359 }
1360 return true;
1361 }
1362
1363 Bool
apc_gp_set_line_width(Handle self,float lineWidth)1364 apc_gp_set_line_width( Handle self, float lineWidth)
1365 {
1366 objCheck false;
1367 if ( !sys ps) {
1368 sys lineWidth = lineWidth;
1369 } else {
1370 PStylus s = &sys stylus;
1371 PEXTPEN ep = &s-> extPen;
1372 if ( lineWidth < 0.0 || lineWidth > 8192.0) lineWidth = 0.0;
1373 s-> pen. lopnWidth. x = lineWidth + .5;
1374 ep-> lineWidth = lineWidth;
1375 if (( ep-> actual = stylus_extpenned( s)))
1376 ep-> style = stylus_get_extpen_style( s);
1377 stylus_change( self);
1378 }
1379 return true;
1380 }
1381
1382 Bool
apc_gp_set_line_pattern(Handle self,unsigned char * pattern,int len)1383 apc_gp_set_line_pattern( Handle self, unsigned char * pattern, int len)
1384 {
1385 objCheck false;
1386 if ( !sys ps) {
1387 if ( sys linePatternLen > sizeof(sys linePattern))
1388 free( sys linePattern);
1389 if ( len > sizeof(sys linePattern)) {
1390 sys linePattern = ( unsigned char *) malloc( len);
1391 if ( !sys linePattern) {
1392 sys linePatternLen = 0;
1393 return false;
1394 }
1395 memcpy( sys linePattern, pattern, len);
1396 } else
1397 memcpy( &sys linePattern, pattern, len);
1398 sys linePatternLen = len;
1399 } else {
1400 PStylus s = &sys stylus;
1401 PEXTPEN ep = &s-> extPen;
1402
1403 s-> pen. lopnStyle = patres_user( pattern, len);
1404 if (( ep-> actual = stylus_extpenned( s))) {
1405 ep-> style = stylus_get_extpen_style( s);
1406 ep-> patResource = ( s-> pen. lopnStyle == PS_USERSTYLE) ?
1407 patres_fetch( pattern, len) : &hPatHollow;
1408 } else
1409 ep-> patResource = &hPatHollow;
1410 stylus_change( self);
1411 }
1412 return true;
1413 }
1414
1415 Bool
apc_gp_set_miter_limit(Handle self,float miter_limit)1416 apc_gp_set_miter_limit( Handle self, float miter_limit)
1417 {
1418 objCheck false;
1419 if ( !sys ps) {
1420 sys miterLimit = miter_limit;
1421 return true;
1422 } else
1423 return SetMiterLimit( sys ps, (FLOAT) miter_limit, NULL);
1424 }
1425
1426
1427 Bool
apc_gp_set_palette(Handle self)1428 apc_gp_set_palette( Handle self)
1429 {
1430 HPALETTE pal;
1431
1432 objCheck false;
1433 if ( sys p256) {
1434 free( sys p256);
1435 sys p256 = NULL;
1436 }
1437
1438 pal = palette_create( self);
1439 if ( sys ps) {
1440 if ( pal)
1441 SelectPalette( sys ps, pal, 0);
1442 else
1443 SelectPalette( sys ps, sys stockPalette, 1);
1444 RealizePalette( sys ps);
1445 }
1446 if ( sys pal) DeleteObject( sys pal);
1447 sys pal = pal;
1448 return true;
1449 }
1450
1451 Bool
apc_gp_set_rop(Handle self,int rop)1452 apc_gp_set_rop( Handle self, int rop)
1453 {
1454 objCheck false;
1455 if ( !sys ps) { sys rop = rop; return true; }
1456 sys currentROP = ctx_remap_def( rop, ctx_rop2R2, true, R2_COPYPEN);
1457 if ( !SetROP2( sys ps, sys currentROP)) apiErr;
1458 return true;
1459 }
1460
1461 Bool
apc_gp_set_rop2(Handle self,int rop)1462 apc_gp_set_rop2( Handle self, int rop)
1463 {
1464 objCheck false;
1465 if ( !sys ps) { sys rop2 = rop; return true; }
1466 if ( rop != ropCopyPut) rop = ropNoOper;
1467 sys currentROP2 = rop;
1468 if ( !SetBkMode( sys ps, ( rop == ropCopyPut) ? OPAQUE : TRANSPARENT)) apiErr;
1469 STYLUS_FREE_GP_BRUSH;
1470 return true;
1471 }
1472
1473 Bool
apc_gp_set_transform(Handle self,int x,int y)1474 apc_gp_set_transform( Handle self, int x, int y)
1475 {
1476 objCheck false;
1477 if ( !sys ps) {
1478 sys transform. x = x;
1479 sys transform. y = y;
1480 return true;
1481 }
1482 sys gp_transform.x = x - sys transform2.x;
1483 sys gp_transform.y = - ( y + sys transform2.y );
1484 return true;
1485 }
1486
1487 #ifdef __cplusplus
1488 }
1489 #endif
1490