/[gnustep]/gnustep/core/back/Source/winlib/WIN32GState.m
ViewVC logotype

Contents of /gnustep/core/back/Source/winlib/WIN32GState.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (show annotations) (download)
Thu Feb 6 12:09:17 2003 UTC (21 years, 3 months ago) by CaS
Branch: MAIN
CVS Tags: pre-header-reorg-20030731, back-0_8_9, back-0_8_4, back-0_8_8, back-0_9_0, back-0_8_5, back-0_8_6, back-0_8_7
Branch point for: freeze-1_8_0, freeze-0_8_5
Changes since 1.10: +20 -0 lines
Support drawing of glyphs for new text system

1 /* WIN32GState - Implements graphic state drawing for MSWindows
2
3 Copyright (C) 2002 Free Software Foundation, Inc.
4
5 Written by: <author name="Fred Kiefer><email>FredKiefer@gmx.de</email></author>
6 Date: March 2002
7
8 This file is part of the GNU Objective C User Interface Library.
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public
21 License along with this library; if not, write to the Free
22 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
23 */
24
25 #include <AppKit/NSAffineTransform.h>
26 #include <AppKit/NSBezierPath.h>
27 #include <AppKit/NSColor.h>
28 #include <AppKit/NSFont.h>
29 #include <AppKit/NSGraphics.h>
30
31 #include "winlib/WIN32GState.h"
32 #include "winlib/WIN32Context.h"
33 #include "winlib/WIN32FontInfo.h"
34 #include "win32/WIN32Server.h"
35
36 #include <math.h>
37
38 static inline
39 int WindowHeight(HWND window)
40 {
41 RECT rect;
42
43 if (!window)
44 {
45 NSLog(@"No window for coordinate transformation.");
46 return 0;
47 }
48
49 if (!GetClientRect(window, &rect))
50 {
51 NSLog(@"No window rectangle for coordinate transformation.");
52 return 0;
53 }
54
55 return rect.bottom - rect.top;
56 }
57
58 static inline
59 POINT GSWindowPointToMS(WIN32GState *s, NSPoint p)
60 {
61 POINT p1;
62 int h;
63
64 h = WindowHeight([s window]);
65
66 p.x += s->offset.x;
67 p.y += s->offset.y;
68 p1.x = p.x;
69 p1.y = h -p.y;
70
71 return p1;
72 }
73
74 static inline
75 RECT GSWindowRectToMS(WIN32GState *s, NSRect r)
76 {
77 RECT r1;
78 int h;
79
80 h = WindowHeight([s window]);
81
82 r.origin.x += s->offset.x;
83 r.origin.y += s->offset.y;
84
85 r1.left = r.origin.x;
86 r1.right = r.origin.x + r.size.width;
87 r1.bottom = h - r.origin.y;
88 r1.top = h - r.origin.y - r.size.height;
89
90 return r1;
91 }
92
93 static inline
94 POINT GSViewPointToWin(WIN32GState *s, NSPoint p)
95 {
96 p = [s->ctm pointInMatrixSpace: p];
97 return GSWindowPointToMS(s, p);
98 }
99
100 static inline
101 RECT GSViewRectToWin(WIN32GState *s, NSRect r)
102 {
103 r = [s->ctm rectInMatrixSpace: r];
104 return GSWindowRectToMS(s, r);
105 }
106
107 @interface WIN32GState (WinOps)
108 - (void) setStyle: (HDC)hDC;
109 - (void) restoreStyle: (HDC)hDC;
110 - (HDC) getHDC;
111 - (void) releaseHDC: (HDC)hDC;
112 @end
113
114 @implementation WIN32GState
115
116 - (id) deepen
117 {
118 [super deepen];
119
120 if (clipRegion)
121 {
122 HRGN newClipRegion;
123
124 newClipRegion = CreateRectRgn(0, 0, 1, 1);
125 CombineRgn(newClipRegion, clipRegion, NULL, RGN_COPY);
126 clipRegion = newClipRegion;
127 }
128
129 oldBrush = NULL;
130 oldPen = NULL;
131 oldClipRegion = NULL;
132
133 return self;
134 }
135
136 - (void) dealloc
137 {
138 DeleteObject(clipRegion);
139 [super dealloc];
140 }
141
142 - (void) setWindow: (HWND)number
143 {
144 window = number;
145 }
146
147 - (HWND) window
148 {
149 return window;
150 }
151
152 - (void) setColor: (device_color_t *)acolor state: (color_state_t)cState
153 {
154 device_color_t color;
155 [super setColor: acolor state: cState];
156 color = *acolor;
157 gsColorToRGB(&color);
158 if (cState & COLOR_FILL)
159 wfcolor = RGB(color.field[0]*255, color.field[1]*255, color.field[2]*255);
160 if (cState & COLOR_STROKE)
161 wscolor = RGB(color.field[0]*255, color.field[1]*255, color.field[2]*255);
162 }
163
164 - (void) copyBits: (WIN32GState*)source
165 fromRect: (NSRect)aRect
166 toPoint: (NSPoint)aPoint
167 {
168 HDC otherDC;
169 HDC hDC;
170 POINT p;
171 RECT rect;
172 int h;
173 int y1;
174
175 p = GSViewPointToWin(self, aPoint);
176 rect = GSViewRectToWin(source, aRect);
177 h = rect.bottom - rect.top;
178
179 if (viewIsFlipped)
180 y1 = p.y;
181 else
182 y1 = p.y - h;
183
184 otherDC = [source getHDC];
185 if (!otherDC)
186 {
187 return;
188 }
189 hDC = [self getHDC];
190 if (!hDC)
191 {
192 [source releaseHDC: otherDC];
193 return;
194 }
195
196 if (!BitBlt(hDC, p.x, y1, (rect.right - rect.left), h,
197 otherDC, rect.left, rect.top, SRCCOPY))
198 {
199 NSLog(@"Copy bitmap failed %d", GetLastError());
200 NSLog(@"Orig Copy Bits to %f, %f from %@", aPoint.x, aPoint.y,
201 NSStringFromRect(aRect));
202 NSLog(@"Copy Bits to %d %d from %d %d size %d %d", p.x , y1,
203 rect.left, rect.top, (rect.right - rect.left), h);
204 }
205 [self releaseHDC: hDC];
206 [source releaseHDC: otherDC];
207 }
208
209 - (void) compositeGState: (GSGState *)source
210 fromRect: (NSRect)aRect
211 toPoint: (NSPoint)aPoint
212 op: (NSCompositingOperation)op
213 {
214 // FIXME
215 [self copyBits: (WIN32GState *)source fromRect: aRect toPoint: aPoint];
216 }
217
218 - (void) dissolveGState: (GSGState *)source
219 fromRect: (NSRect)aRect
220 toPoint: (NSPoint)aPoint
221 delta: (float)delta
222 {
223 // FIXME
224 [self copyBits: (WIN32GState *)source fromRect: aRect toPoint: aPoint];
225 }
226
227 - (void) compositerect: (NSRect)aRect
228 op: (NSCompositingOperation)op
229 {
230 float gray;
231
232 [self DPScurrentgray: &gray];
233 if (fabs(gray - 0.667) < 0.005)
234 [self DPSsetgray: 0.333];
235 else
236 [self DPSsetrgbcolor: 0.121 : 0.121 : 0];
237
238 switch (op)
239 {
240 case NSCompositeClear:
241 break;
242 case NSCompositeHighlight:
243 {
244 HDC hDC;
245 RECT rect = GSViewRectToWin(self, aRect);
246
247 hDC = [self getHDC];
248 if (!hDC)
249 {
250 return;
251 }
252
253 InvertRect(hDC, &rect);
254 [self releaseHDC: hDC];
255 break;
256 }
257 case NSCompositeCopy:
258 // FIXME
259 case NSCompositeSourceOver:
260 case NSCompositeSourceIn:
261 case NSCompositeSourceOut:
262 case NSCompositeSourceAtop:
263 case NSCompositeDestinationOver:
264 case NSCompositeDestinationIn:
265 case NSCompositeDestinationOut:
266 case NSCompositeDestinationAtop:
267 case NSCompositeXOR:
268 case NSCompositePlusDarker:
269 case NSCompositePlusLighter:
270 default:
271 [self DPSrectfill: NSMinX(aRect) : NSMinY(aRect)
272 : NSWidth(aRect) : NSHeight(aRect)];
273 break;
274 }
275 }
276
277
278 static
279 HBITMAP GSCreateBitmap(HDC hDC, int pixelsWide, int pixelsHigh,
280 int bitsPerSample, int samplesPerPixel,
281 int bitsPerPixel, int bytesPerRow,
282 BOOL isPlanar, BOOL hasAlpha,
283 NSString *colorSpaceName,
284 const unsigned char *const data[5])
285 {
286 HBITMAP hbitmap;
287 BITMAPINFO *bitmap;
288 BITMAPINFOHEADER *bmih;
289 int xres, yres;
290 UINT fuColorUse;
291
292 if (isPlanar || ![colorSpaceName isEqualToString: NSDeviceRGBColorSpace])
293 {
294 NSLog(@"Bitmap type currently not supported %d %@", isPlanar, colorSpaceName);
295 return NULL;
296 }
297
298 // default is 8 bit grayscale
299 if (!bitsPerSample)
300 bitsPerSample = 8;
301 if (!samplesPerPixel)
302 samplesPerPixel = 1;
303
304 // FIXME - does this work if we are passed a planar image but no hints ?
305 if (!bitsPerPixel)
306 bitsPerPixel = bitsPerSample * samplesPerPixel;
307 if (!bytesPerRow)
308 bytesPerRow = (bitsPerPixel * pixelsWide) / 8;
309
310 // make sure its sane - also handles row padding if hint missing
311 while((bytesPerRow * 8) < (bitsPerPixel * pixelsWide))
312 bytesPerRow++;
313
314 if (!(GetDeviceCaps(hDC, RASTERCAPS) & RC_DI_BITMAP))
315 {
316 return NULL;
317 }
318
319 hbitmap = CreateCompatibleBitmap(hDC, pixelsWide, pixelsHigh);
320 if (!hbitmap)
321 {
322 return NULL;
323 }
324
325 if (bitsPerPixel > 8)
326 {
327 bitmap = objc_malloc(sizeof(BITMAPV4HEADER));
328 }
329 else
330 {
331 bitmap = objc_malloc(sizeof(BITMAPINFOHEADER) +
332 (1 << bitsPerPixel) * sizeof(RGBQUAD));
333 }
334 bmih = (BITMAPINFOHEADER*)bitmap;
335
336 bmih->biSize = sizeof(BITMAPINFOHEADER);
337 bmih->biWidth = pixelsWide;
338 bmih->biHeight = -pixelsHigh;
339 bmih->biPlanes = 1;
340 bmih->biBitCount = bitsPerPixel;
341 bmih->biCompression = BI_RGB;
342 bmih->biSizeImage = 0;
343 xres = GetDeviceCaps(hDC, HORZRES) / GetDeviceCaps(hDC, HORZSIZE);
344 yres = GetDeviceCaps(hDC, VERTRES) / GetDeviceCaps(hDC, VERTSIZE);
345 bmih->biXPelsPerMeter = xres;
346 bmih->biYPelsPerMeter = yres;
347 bmih->biClrUsed = 0;
348 bmih->biClrImportant = 0;
349 fuColorUse = 0;
350
351 if (bitsPerPixel <= 8)
352 {
353 // FIXME How to get a colour palette?
354 NSLog(@"Need to define colour map for images with %d bits", bitsPerPixel);
355 //bitmap->bmiColors;
356 fuColorUse = DIB_RGB_COLORS;
357 }
358 else if (bitsPerPixel == 32)
359 {
360 BITMAPV4HEADER *bmih;
361
362 bmih = (BITMAPV4HEADER*)bitmap;
363 bmih->bV4Size = sizeof(BITMAPV4HEADER);
364 bmih->bV4V4Compression = BI_BITFIELDS;
365 bmih->bV4RedMask = 0x000000FF;
366 bmih->bV4GreenMask = 0x0000FF00;
367 bmih->bV4BlueMask = 0x00FF0000;
368 bmih->bV4AlphaMask = 0xFF000000;
369 }
370 else if (bitsPerPixel == 16)
371 {
372 /*
373 BITMAPV4HEADER *bmih;
374
375 bmih = (BITMAPV4HEADER*)bitmap;
376 bmih->bV4Size = sizeof(BITMAPV4HEADER);
377 bmih->bV4V4Compression = BI_BITFIELDS;
378 bmih->bV4RedMask = 0xF000;
379 bmih->bV4GreenMask = 0x0F00;
380 bmih->bV4BlueMask = 0x00F0;
381 bmih->bV4AlphaMask = 0x000F;
382 */
383 NSLog(@"Unsure how to handle images with %d bits", bitsPerPixel);
384 }
385
386 if (!SetDIBits(hDC, hbitmap, 0, pixelsHigh, data[0],
387 bitmap, fuColorUse))
388 {
389 objc_free(bitmap);
390 DeleteObject(hbitmap);
391 return NULL;
392 }
393
394 objc_free(bitmap);
395 return hbitmap;
396 }
397
398 - (void)DPSimage: (NSAffineTransform*) matrix
399 : (int) pixelsWide : (int) pixelsHigh
400 : (int) bitsPerSample : (int) samplesPerPixel
401 : (int) bitsPerPixel : (int) bytesPerRow : (BOOL) isPlanar
402 : (BOOL) hasAlpha : (NSString *) colorSpaceName
403 : (const unsigned char *const [5]) data
404 {
405 NSAffineTransform *old_ctm = nil;
406 HDC hDC;
407 HBITMAP hbitmap;
408 HGDIOBJ old;
409 HDC hDC2;
410 POINT p;
411 int h;
412 int y1;
413
414 if (window == NULL)
415 {
416 NSLog(@"No window in DPSImage");
417 return;
418 }
419
420 hDC = GetDC((HWND)window);
421 if (!hDC)
422 {
423 NSLog(@"No DC for window %d in DPSImage. Error %d",
424 (int)window, GetLastError());
425 }
426
427 hbitmap = GSCreateBitmap(hDC, pixelsWide, pixelsHigh,
428 bitsPerSample, samplesPerPixel,
429 bitsPerPixel, bytesPerRow,
430 isPlanar, hasAlpha,
431 colorSpaceName, data);
432 if (!hbitmap)
433 {
434 NSLog(@"Created bitmap failed %d", GetLastError());
435 }
436
437 hDC2 = CreateCompatibleDC(hDC);
438 if (!hDC2)
439 {
440 NSLog(@"No Compatible DC for window %d in DPSImage. Error %d",
441 (int)window, GetLastError());
442 }
443 old = SelectObject(hDC2, hbitmap);
444 if (!old)
445 {
446 NSLog(@"SelectObject failed for window %d in DPSImage. Error %d",
447 (int)window, GetLastError());
448 }
449
450 //SetMapMode(hDC2, GetMapMode(hDC));
451 ReleaseDC((HWND)window, hDC);
452
453 hDC = [self getHDC];
454
455 h = pixelsHigh;
456 // Apply the additional transformation
457 if (matrix)
458 {
459 old_ctm = [ctm copy];
460 [ctm appendTransform: matrix];
461 }
462 p = GSViewPointToWin(self, NSMakePoint(0, 0));
463 if (old_ctm != nil)
464 {
465 RELEASE(ctm);
466 // old_ctm is already retained
467 ctm = old_ctm;
468 }
469 if (viewIsFlipped)
470 y1 = p.y;
471 else
472 y1 = p.y - h;
473
474 if (!BitBlt(hDC, p.x, y1, pixelsWide, pixelsHigh,
475 hDC2, 0, 0, SRCCOPY))
476 {
477 NSLog(@"Copy bitmap failed %d", GetLastError());
478 NSLog(@"DPSimage with %d %d %d %d to %d, %d", pixelsWide, pixelsHigh,
479 bytesPerRow, bitsPerPixel, p.x, y1);
480 }
481
482 [self releaseHDC: hDC];
483
484 SelectObject(hDC2, old);
485 DeleteDC(hDC2);
486 DeleteObject(hbitmap);
487 }
488
489 @end
490
491 @implementation WIN32GState (PathOps)
492
493 - (void) _paintPath: (ctxt_object_t) drawType
494 {
495 unsigned count;
496 HDC hDC;
497
498 hDC = [self getHDC];
499 if (!hDC)
500 {
501 return;
502 }
503
504 count = [path elementCount];
505 if (count)
506 {
507 NSBezierPathElement type;
508 NSPoint points[3];
509 unsigned j, i = 0;
510 POINT p;
511
512 BeginPath(hDC);
513
514 for(j = 0; j < count; j++)
515 {
516 type = [path elementAtIndex: j associatedPoints: points];
517 switch(type)
518 {
519 case NSMoveToBezierPathElement:
520 p = GSWindowPointToMS(self, points[0]);
521 MoveToEx(hDC, p.x, p.y, NULL);
522 break;
523 case NSLineToBezierPathElement:
524 p = GSWindowPointToMS(self, points[0]);
525 // FIXME This gives one pixel to few
526 LineTo(hDC, p.x, p.y);
527 break;
528 case NSCurveToBezierPathElement:
529 {
530 POINT bp[3];
531
532 for (i = 1; i < 3; i++)
533 {
534 bp[i] = GSWindowPointToMS(self, points[i]);
535 }
536 PolyBezierTo(hDC, bp, 3);
537 }
538 break;
539 case NSClosePathBezierPathElement:
540 CloseFigure(hDC);
541 break;
542 default:
543 break;
544 }
545 }
546 EndPath(hDC);
547
548 // Now operate on the path
549 switch (drawType)
550 {
551 case path_stroke:
552 StrokePath(hDC);
553 break;
554 case path_eofill:
555 SetPolyFillMode(hDC, ALTERNATE);
556 FillPath(hDC);
557 break;
558 case path_fill:
559 SetPolyFillMode(hDC, WINDING);
560 FillPath(hDC);
561 break;
562 case path_eoclip:
563 {
564 HRGN region;
565
566 SetPolyFillMode(hDC, ALTERNATE);
567 region = PathToRegion(hDC);
568 if (clipRegion)
569 {
570 CombineRgn(clipRegion, clipRegion, region, RGN_AND);
571 DeleteObject(region);
572 }
573 else
574 {
575 clipRegion = region;
576 }
577 break;
578 }
579 case path_clip:
580 {
581 HRGN region;
582
583 SetPolyFillMode(hDC, WINDING);
584 region = PathToRegion(hDC);
585 if (clipRegion)
586 {
587 CombineRgn(clipRegion, clipRegion, region, RGN_AND);
588 DeleteObject(region);
589 }
590 else
591 {
592 clipRegion = region;
593 }
594 break;
595 }
596 default:
597 break;
598 }
599 }
600 [self releaseHDC: hDC];
601
602 /*
603 * clip does not delete the current path, so we only clear the path if the
604 * operation was not a clipping operation.
605 */
606 if ((drawType != path_clip) && (drawType != path_eoclip))
607 {
608 [path removeAllPoints];
609 }
610 }
611
612 - (void)DPSclip
613 {
614 [self _paintPath: path_clip];
615 }
616
617 - (void)DPSeoclip
618 {
619 [self _paintPath: path_eoclip];
620 }
621
622 - (void)DPSeofill
623 {
624 [self _paintPath: path_eofill];
625 }
626
627 - (void)DPSfill
628 {
629 [self _paintPath: path_fill];
630 }
631
632 - (void)DPSstroke
633 {
634 [self _paintPath: path_stroke];
635 }
636
637
638 - (void) DPSinitclip;
639 {
640 if (clipRegion)
641 {
642 DeleteObject(clipRegion);
643 clipRegion = NULL;
644 }
645 }
646
647 - (void)DPSrectfill: (float)x : (float)y : (float)w : (float)h
648 {
649 HDC hDC;
650 HBRUSH brush;
651 RECT rect;
652
653 hDC = [self getHDC];
654 if (!hDC)
655 {
656 return;
657 }
658
659 brush = GetCurrentObject(hDC, OBJ_BRUSH);
660 rect = GSViewRectToWin(self, NSMakeRect(x, y, w, h));
661 FillRect(hDC, &rect, brush);
662 [self releaseHDC: hDC];
663 }
664
665 - (void)DPSrectstroke: (float)x : (float)y : (float)w : (float)h
666 {
667 NSRect rect = [ctm rectInMatrixSpace: NSMakeRect(x, y, w, h)];
668 NSBezierPath *oldPath = path;
669
670 // Samll adjustment so that the line is visible
671 if (rect.size.width > 0)
672 rect.size.width--;
673 if (rect.size.height > 0)
674 rect.size.height--;
675 rect.origin.y += 1;
676
677 path = [NSBezierPath bezierPathWithRect: rect];
678 [self DPSstroke];
679 path = oldPath;
680 }
681
682 - (void)DPSrectclip: (float)x : (float)y : (float)w : (float)h
683 {
684 RECT rect;
685 HRGN region;
686
687 rect = GSViewRectToWin(self, NSMakeRect(x, y, w, h));
688 region = CreateRectRgnIndirect(&rect);
689 if (clipRegion)
690 {
691 CombineRgn(clipRegion, clipRegion, region, RGN_AND);
692 DeleteObject(region);
693 }
694 else
695 {
696 clipRegion = region;
697 }
698 }
699
700 - (void)DPSshow: (const char *)s
701 {
702 NSPoint current = [path currentPoint];
703 POINT p;
704 HDC hDC;
705
706 hDC = [self getHDC];
707 if (!hDC)
708 {
709 return;
710 }
711
712 p = GSWindowPointToMS(self, current);
713 [(WIN32FontInfo*)font draw: s lenght: strlen(s)
714 onDC: hDC at: p];
715 [self releaseHDC: hDC];
716 }
717
718 - (void) GSShowGlyphs: (const NSGlyph *)glyphs : (size_t)length
719 {
720 NSPoint current = [path currentPoint];
721 POINT p;
722 HDC hDC;
723
724 hDC = [self getHDC];
725 if (!hDC)
726 {
727 return;
728 }
729
730 p = GSWindowPointToMS(self, current);
731 [(WIN32FontInfo*)font drawGlyphs: glyphs
732 length: length
733 onDC: hDC
734 at: p];
735 [self releaseHDC: hDC];
736 }
737 @end
738
739 @implementation WIN32GState (GStateOps)
740
741 - (void)DPSinitgraphics
742 {
743 [super DPSinitgraphics];
744 }
745
746 - (void) DPSsetdash: (const float*)pattern : (int)count : (float)phase
747 {
748 if (!path)
749 {
750 path = [NSBezierPath new];
751 }
752
753 [path setLineDash: pattern count: count phase: phase];
754 }
755
756 - (void)DPScurrentmiterlimit: (float *)limit
757 {
758 *limit = miterlimit;
759 }
760
761 - (void)DPSsetmiterlimit: (float)limit
762 {
763 miterlimit = limit;
764 }
765
766 - (void)DPScurrentlinecap: (int *)linecap
767 {
768 *linecap = lineCap;
769 }
770
771 - (void)DPSsetlinecap: (int)linecap
772 {
773 lineCap = linecap;
774 }
775
776 - (void)DPScurrentlinejoin: (int *)linejoin
777 {
778 *linejoin = joinStyle;
779 }
780
781 - (void)DPSsetlinejoin: (int)linejoin
782 {
783 joinStyle = linejoin;
784 }
785
786 - (void)DPScurrentlinewidth: (float *)width
787 {
788 *width = lineWidth;
789 }
790
791 - (void)DPSsetlinewidth: (float)width
792 {
793 lineWidth = width;
794 }
795
796 - (void)DPScurrentstrokeadjust: (int *)b
797 {
798 }
799
800 - (void)DPSsetstrokeadjust: (int)b
801 {
802 }
803
804 @end
805
806 @implementation WIN32GState (WinOps)
807
808 - (void) setStyle: (HDC)hDC
809 {
810 HPEN pen;
811 HBRUSH brush;
812 LOGBRUSH br;
813 int join;
814 int cap;
815 DWORD penStyle;
816 SetBkMode(hDC, TRANSPARENT);
817 /*
818 br.lbStyle = BS_SOLID;
819 br.lbColor = color;
820 brush = CreateBrushIndirect(&br);
821 */
822 brush = CreateSolidBrush(wfcolor);
823 oldBrush = SelectObject(hDC, brush);
824
825 switch (joinStyle)
826 {
827 case NSBevelLineJoinStyle:
828 join = PS_JOIN_BEVEL;
829 break;
830 case NSMiterLineJoinStyle:
831 join = PS_JOIN_MITER;
832 break;
833 case NSRoundLineJoinStyle:
834 join = PS_JOIN_ROUND;
835 break;
836 default:
837 join = PS_JOIN_MITER;
838 break;
839 }
840
841 switch (lineCap)
842 {
843 case NSButtLineCapStyle:
844 cap = PS_ENDCAP_FLAT;
845 break;
846 case NSSquareLineCapStyle:
847 cap = PS_ENDCAP_SQUARE;
848 break;
849 case NSRoundLineCapStyle:
850 cap = PS_ENDCAP_ROUND;
851 break;
852 default:
853 cap = PS_ENDCAP_SQUARE;
854 break;
855 }
856
857 penStyle = PS_GEOMETRIC | PS_SOLID;
858 if (path)
859 {
860 float pattern[10];
861 int count = 10;
862 float phase;
863
864 [path getLineDash: pattern count: &count phase: &phase];
865
866 if (count && (count < 10))
867 {
868 penStyle = PS_GEOMETRIC | PS_DASH;
869 }
870 }
871
872 pen = ExtCreatePen(penStyle | join | cap,
873 lineWidth,
874 &br,
875 0, NULL);
876
877 oldPen = SelectObject(hDC, pen);
878
879 SetMiterLimit(hDC, miterlimit, NULL);
880
881 SetTextColor(hDC, wfcolor);
882
883 oldClipRegion = CreateRectRgn(0, 0, 1, 1);
884 if (1 != GetClipRgn(hDC, oldClipRegion))
885 {
886 DeleteObject(oldClipRegion);
887 oldClipRegion = NULL;
888 }
889
890 SelectClipRgn(hDC, clipRegion);
891 }
892
893 - (void) restoreStyle: (HDC)hDC
894 {
895 HGDIOBJ old;
896
897 SelectClipRgn(hDC, oldClipRegion);
898 DeleteObject(oldClipRegion);
899 oldClipRegion = NULL;
900
901 old = SelectObject(hDC, oldBrush);
902 DeleteObject(old);
903
904 old = SelectObject(hDC, oldPen);
905 DeleteObject(old);
906 }
907
908 - (HDC) getHDC
909 {
910 WIN_INTERN *win;
911 HDC hDC;
912
913 if (NULL == window)
914 {
915 //Log(@"No window in getHDC");
916 return NULL;
917 }
918
919 win = (WIN_INTERN *)GetWindowLong((HWND)window, GWL_USERDATA);
920 if (win && win->useHDC)
921 {
922 hDC = win->hdc;
923 //NSLog(@"getHDC found DC %d", hDC);
924 }
925 else
926 {
927 hDC = GetDC((HWND)window);
928 //NSLog(@"getHDC using window DC %d", hDC);
929 }
930
931 if (!hDC)
932 {
933 //Log(@"No DC in getHDC");
934 return NULL;
935 }
936
937 [self setStyle: hDC];
938 return hDC;
939 }
940
941 - (void) releaseHDC: (HDC)hDC
942 {
943 WIN_INTERN *win;
944
945 if (NULL == window ||
946 NULL == hDC)
947 {
948 return;
949 }
950
951 [self restoreStyle: hDC];
952 win = (WIN_INTERN *)GetWindowLong((HWND)window, GWL_USERDATA);
953 if (win && !win->useHDC)
954 ReleaseDC((HWND)window, hDC);
955 }
956
957 @end

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26