0023947: Eliminate trivial compiler warnings in MSVC++ with warning level 4
[occt.git] / src / WNT / EHDC.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19// Modifications: PLOTNIKOV Eugeny at July 1998 (BUC60286)
7fd59977 20
21#include "EHDC.hxx"
22
23#include <math.h>
24#include <limits>
25
26#define ROUNDL( d ) ( LONG )( ( d ) + 0.5 )
27#define Y( y ) ( mySize.cy - ( y ) )
28
29typedef struct _fpoint {
30
31 FLOAT x;
32 FLOAT y;
33
34 } FPOINT, *PFPOINT;
35
36typedef struct _ddap {
37
38 EHDC* _this;
39 PPOINT pp;
40
41 } DDAP, *PDDAP;
42
43static void WINAPI _XFORMultiply ( PXFORM, PXFORM, PXFORM );
44static void WINAPI _XFORMApply ( PPOINT, int, PXFORM );
45static void WINAPI _XFORMApplyf ( PFPOINT, int, PXFORM );
46
47static void WINAPI _RenderPath ( HDC, LPPOINT, PBYTE, int );
48static int WINAPI _TextPath ( HDC, int, int, void*, LPPOINT, PBYTE, int, PSIZE, BOOL );
49
50EHDC :: EHDC ( HDC hdc, PSIZE szClient ) {
51
52 _Init ();
53
54 SetDC ( hdc, szClient );
55
56} // end EHDC constructor ( 1 )
57
58EHDC :: EHDC () {
59
60 _Init ();
61
62} // end EHDC constructor ( 2 )
63
64EHDC :: ~EHDC () {
65
66 HANDLE hHeap = GetProcessHeap ();
67
68 if ( myHDC != NULL ) {
69
70 SelectPen( myHDC, GetStockObject ( NULL_PEN ) );
71 SelectBrush( myHDC, GetStockObject ( NULL_BRUSH ) );
72
73 } // end if
74
75 if ( myTextBrush != NULL ) DeleteBrush( myTextBrush );
76 if ( myTextPen != NULL ) DeletePen( myTextPen );
77
78 if ( myTextPath != NULL ) HeapFree (
79 hHeap, 0,
80 ( LPVOID )myTextPath
81 );
82 if ( myPStyle != NULL && ( myFlags & EHDCF_SFREE ) )
83
84 HeapFree ( hHeap, 0, ( LPVOID )myPStyle );
85
86 if ( myPBrush != NULL ) DeleteBrush( myPBrush );
87 if ( myPPen != NULL ) DeletePen( myPPen );
88
89 if ( myFlags & EHDCF_PPUSH ) {
90
91 if ( myPPenPush != NULL ) DeletePen( myPPenPush );
92 if ( myPBrushPush != NULL ) DeleteBrush( myPBrushPush );
93
94 } // end if
95
96 HeapFree ( hHeap, 0, ( LPVOID )myDDA1 );
97 HeapFree ( hHeap, 0, ( LPVOID )myDDA2 );
98
99} // end EHDC destructor
100
101void EHDC :: SetDC ( HDC hdc, PSIZE szClient ) {
102
103 myHDC = hdc;
104 myTextHScale =
105 myTextVScale = 1.0;
106 myTextSlant = 0.0;
107 mySize = *szClient;
108
109 SelectPen( myHDC, myPPen );
110 SelectBrush( myHDC, myPBrush );
111
112 MoveToEx ( 0, 0, NULL );
113 ResetURect ();
114
115} // end EHDC :: SetDC
116
117HBRUSH EHDC :: SelectEPen (
118 DWORD dwWidth,
119 CONST LOGBRUSH* lplb,
120 DWORD dwStyleCount,
121 DWORD* lpStyle,
122 BOOL fNoAlloc
123 ) {
124
125 DWORD dwLen = dwStyleCount * sizeof ( DWORD );
126
127 if ( dwStyleCount ) {
128
129 if ( !fNoAlloc ) {
130
131 if ( myPStyle == NULL ) {
132
133 myPStyle = ( PDWORD )HeapAlloc (
134 GetProcessHeap (),
135 HEAP_GENERATE_EXCEPTIONS,
136 dwLen
137 );
138setPBS:
139 myPBS = dwStyleCount;
140
141 } else if ( myPBS < dwStyleCount ) {
142
143 myPStyle = ( PDWORD )HeapReAlloc (
144 GetProcessHeap (),
145 HEAP_GENERATE_EXCEPTIONS,
146 myPStyle, dwLen
147 );
148
149 goto setPBS;
150
151 } // end if
152
153 CopyMemory ( myPStyle, lpStyle, dwLen );
154 myFlags |= EHDCF_SFREE;
155
156 } else if ( myPStyle != NULL && ( myFlags & EHDCF_SFREE ) ) {
157
158 HeapFree ( GetProcessHeap (), 0, ( LPVOID )myPStyle );
159 myPStyle = lpStyle;
160
161 } // end if
162
163 } // end if
164
165 myPIndex = 0;
166 myPWidth = dwWidth;
167 myPNS = dwStyleCount;
168
169 if ( myPBrush != NULL ) {
170
171 LOGBRUSH lb;
172
173 GetObject ( myPBrush, sizeof ( LOGBRUSH ), &lb );
174
175 if ( lb.lbStyle != lplb -> lbStyle ||
176 lb.lbColor != lplb -> lbColor ||
177 lb.lbHatch != lplb -> lbHatch
178 ) {
179
180 SelectBrush( myHDC, GetStockObject ( NULL_BRUSH ) );
181 DeleteBrush( myPBrush );
182newBrush:
183 myPBrush = CreateBrushIndirect ( lplb );
184
185 } // end if
186
187 if ( dwWidth > 1 ) {
188
189 myFlags |= ( EHDCF_EPEN | EHDCF_PDRAW | EHDCF_CJOIN );
190 myFlags &= ~EHDCF_JOIN;
191
192 } else myFlags &= ~EHDCF_EPEN;
193
194 } else goto newBrush;
195
196 if ( myPPen != NULL ) {
197
198 LOGPEN lp;
199
200 GetObject ( myPPen, sizeof ( LOGPEN ), &lp );
201
202 if ( lp.lopnColor != lplb -> lbColor ||
203 lp.lopnWidth.x != 0
204 ) {
205
206 SelectPen( myHDC, GetStockObject ( NULL_PEN ) );
207 DeletePen( myPPen );
208newPen:
209 myPPen = CreatePen ( PS_SOLID, 0, lplb -> lbColor );
210
211 } // end if
212
213 } else goto newPen;
214
215 SelectPen( myHDC, myPPen );
216
217 return SelectBrush( myHDC, myPBrush );
218
219} // end EHDC :: SelectEPen
220
221void EHDC :: SelectEPen (
222 DWORD dwWidth,
223 CONST LOGBRUSH* lplb
224 ) {
225
226 if ( dwWidth == 0xFFFFFFFF && ( myFlags & EHDCF_PPUSH ) ) {
227
228 SelectPen( myHDC, myPPenPush );
229 SelectBrush( myHDC, myPBrushPush );
230 DeletePen( myPPen );
231 DeleteBrush( myPBrush );
232
233 myFlags &= ~EHDCF_PPUSH;
234 myPPen = myPPenPush;
235 myPBrush = myPBrushPush;
236 myPWidth = myPWPush;
237 myFlags |= ( myfXpenPush ? EHDCF_EPEN : 0 );
238
239 } else if ( !( myFlags & EHDCF_PPUSH ) ){
240
241 myFlags |= EHDCF_PPUSH;
242 myfXpenPush = ( myFlags & EHDCF_EPEN );
243 myPPenPush = myPPen;
244 myPBrushPush = myPBrush;
245 myPWPush = myPWidth;
246
247 myPWidth = dwWidth;
248 SelectBrush( myHDC, myPBrush = CreateBrushIndirect ( lplb ) );
249 SelectPen( myHDC, myPPen = CreatePen ( PS_SOLID, 0, lplb -> lbColor ) );
250
251 if ( dwWidth > 1 ) {
252
253 myFlags |= ( EHDCF_EPEN | EHDCF_PDRAW | EHDCF_CJOIN );
254 myFlags &= ~EHDCF_JOIN;
255
256 } else myFlags &= ~EHDCF_EPEN;
257
258 } // end if
259
260} // end EHDC :: SelectEPen
261
262HPEN EHDC :: SelectEPen ( HPEN hPen ) {
263
264 HPEN retVal = NULL;
265
266 if ( myHDC != NULL ) retVal = SelectPen( myHDC, hPen );
267
268 myFlags &= ~EHDCF_EPEN;
269
270 return hPen;
271
272} // end EHDC :: SelectEPen
273
274void EHDC :: SelectEBrush ( PLOGBRUSH lplb, PLOGBRUSH lplbo ) {
275
276 if ( lplb == NULL ) {
277
278 DeleteBrush( myBrush );
279 myBrush = NULL;
280
281 } else if ( myBrush != NULL ) {
282
283 LOGBRUSH lb;
284
285 GetObject ( myBrush, sizeof ( LOGBRUSH ), &lb );
286
287 if ( lplbo != NULL ) *lplbo = lb;
288
289 if ( lb.lbStyle != lplb -> lbStyle ||
290 lb.lbColor != lplb -> lbColor ||
291 lb.lbHatch != lplb -> lbHatch
292 ) {
293
294 DeleteBrush( myBrush );
295newBrush:
296 myBrush = CreateBrushIndirect ( lplb );
297
298 } // end if
299
300 } else goto newBrush;
301
302} // end EHDC :: SelectEBrush
303
304void EHDC :: SetMiter ( BOOL fMiter ) {
305
306 if ( fMiter )
307
308 myFlags &= ~EHDCF_JBEVL;
309
310 else
311
312 myFlags |= EHDCF_JBEVL;
313
314} // end EHDC :: SetMiter
315
316void EHDC :: MoveToEx ( int x, int y, LPPOINT lpPoint ) {
317
318 if ( lpPoint != NULL ) *lpPoint = myStart;
319
320 myStart.x = x;
321 myStart.y = y;
322
323 if ( myFlags & EHDCF_XFORM ) _XFORMApply ( &myStart, 1, &myXform );
324
325 myStart.y = Y( myStart.y );
326 Register ( &myStart, 1 );
327
328 ::MoveToEx ( myHDC, myStart.x, myStart.y, NULL );
329
330 myClose = myStart;
331 myPIndex = 0;
332 myFlags &= ~EHDCF_JOIN;
333 myFlags |= ( EHDCF_PDRAW | EHDCF_DDAF );
334 myPIndex = 0;
335 myPRlen = 0;
336
337} // end EHDC :: MoveToEx
338
339BOOL EHDC :: LineTo ( int x, int y ) {
340
341 POINT p = { x, y };
342
343 if ( myFlags & EHDCF_XFORM ) _XFORMApply ( &p, 1, &myXform );
344
345 p.y = Y( p.y );
346
347 if ( myFlags & EHDCF_EPEN ) {
348
349 if ( myPNS == 0 )
350
351 _DrawTo ( &p );
352
353 else if ( !_DrawToEx ( &p ) ) return FALSE;
354
355 if ( myFlags & EHDCF_CJOIN ) {
356
357 myFlags &= ~EHDCF_CJOIN;
358 myCJoin = p;
359
360 } // end if
361
362 if ( myFlags & EHDCF_JOIN )
363
364 _Join ();
365
366 else
367
368 myJoin = p;
369
370 if ( myFlags & EHDCF_PDRAW && !( myFlags & EHDCF_NJOIN ) )
371
372 myFlags |= EHDCF_JOIN;
373
374 else
375
376 myFlags &= ~( EHDCF_JOIN | EHDCF_NJOIN );
377
378 } else if ( myPNS == 0 ) {
379
380 Register ( &p, 1 );
381
382 ::LineTo ( myHDC, p.x, p.y );
383
384 myStart = p;
385
386 } else _LineTo ( &p );
387
388 return TRUE;
389
390} // end EHDC :: LineTo
391
392void EHDC :: ClosePath ( void ) {
393
394 BOOL ltf;
395 POINT pa = myStart;
396 POINT pb = myClose;
397 DWORD dw = ( myFlags & EHDCF_XFORM );
398
399 myFlags &= ~EHDCF_XFORM;
400
401 if ( myStart.x != myClose.x ||
402 myStart.y != myClose.y
403 ) {
404
405 ltf = LineTo ( myClose.x, Y( myClose.y ) );
406
407 myFlags |= dw;
408
409 if ( ltf && ( myFlags & EHDCF_PDRAW ) && ( myFlags & EHDCF_EPEN ) ) {
410
411 myA = pa;
412 myB = pb;
413 myStart = myCJoin;
414
415 _Join ();
416
417 } // end if
418
419 } else myFlags |= dw;
420
421 myFlags &= ~EHDCF_JOIN;
422 myPIndex = 0;
423 myFlags |= ( EHDCF_PDRAW | EHDCF_CJOIN );
424 myPRlen = 0;
425
426} // end EHDC :: ClosePath
427
428void EHDC :: Polyline ( CONST POINT* lpPts, int nPts, BOOL fClose ) {
429
430 DWORD dwPIndex = myPIndex;
431 DWORD dwPRlen = myPRlen;
432 DWORD dwFlags = myFlags;
433 POINT pA = myA;
434 POINT pB = myB;
435 POINT pClose = myClose;
436 POINT pJoin = myJoin;
437 POINT pCJoin = myCJoin;
438 POINT pStart;
439
440 myFlags |= EHDCF_CJOIN;
441
442 MoveToEx ( lpPts -> x, lpPts -> y, &pStart );
443
444 for ( int i = 1; i < nPts; ++i )
445
446 LineTo ( lpPts[ i ].x, lpPts[ i ].y );
447
448 if ( fClose ) ClosePath ();
449
450 myFlags = dwFlags;
451 myA = pA;
452 myB = pB;
453 myClose = pClose;
454 myJoin = pJoin;
455 myCJoin = pCJoin;
456 myStart = pStart;
457 myPRlen = dwPRlen;
458 myPIndex = dwPIndex;
459
460} // end EHDC :: Polyline
461
462void EHDC :: Polygon ( CONST POINT* lpPts, int nPts, DWORD dwFlags ) {
463
464 POINT p;
465 HPEN hpo = SelectPen( myHDC, GetStockObject ( NULL_PEN ) );
466 HBRUSH hbo = SelectBrush( myHDC, myBrush ? myBrush : GetStockObject ( NULL_BRUSH ) );
467
468 BeginPath ( myHDC );
469
470 p.x = lpPts -> x;
471 p.y = lpPts -> y;
472
473 if ( myFlags & EHDCF_XFORM ) _XFORMApply ( &p, 1, &myXform );
474
475 ::MoveToEx ( myHDC, p.x, Y( p.y ), NULL );
476
477 for ( int i = 1; i < nPts; ++i ) {
478
479 p.x = lpPts[ i ].x;
480 p.y = lpPts[ i ].y;
481
482 if ( myFlags & EHDCF_XFORM ) _XFORMApply ( &p, 1, &myXform );
483
484 ::LineTo ( myHDC, p.x, Y( p.y ) );
485
486 } // end for
487
488 CloseFigure ( myHDC );
489
490 EndPath ( myHDC );
491
492 FillPath ( myHDC );
493
494 SelectBrush( myHDC, hbo );
495 SelectPen( myHDC, hpo );
496
497 if ( dwFlags & POLYF_NOCLOSEDGE )
498
499 Polyline ( lpPts, nPts, FALSE );
500
501 else if ( !( dwFlags & POLYF_NOEDGE ) )
502
503 Polyline ( lpPts, nPts, TRUE );
504
505} // end EHDC :: Polygon
506
507void EHDC :: Arc (
508 int x, int y, int xr, int yr, double sa, double oa, DWORD dwAFlags
509 ) {
510
511 int i = 0, j, n;
512 double delta;
513 FPOINT fp[ 362 ];
514 BOOL fXform = ( myFlags & EHDCF_XFORM );
515 DWORD dwPIndex = myPIndex;
516 DWORD dwPRlen = myPRlen;
517 DWORD dwFlags = myFlags;
518 POINT pA = myA;
519 POINT pB = myB;
520 POINT pClose = myClose;
521 POINT pJoin = myJoin;
522 POINT pCJoin = myCJoin;
523 POINT pStart = myStart;
524
525 myFlags &= ~EHDCF_XFORM;
526
527 if ( oa > 6.28318 )
528
529 oa = 6.28318;
530
531 else if ( oa < -6.28318 )
532
533 oa = -6.28318;
534
535 n = abs ( ROUNDL( oa * 180.0 / 3.14159 ) );
536 delta = oa / n;
537
538 fp[ i ].x = ( FLOAT )x;
539 fp[ i++ ].y = ( FLOAT )y;
540 n += 2;
541
542 for ( ; i < n; ++i, sa += delta ) {
543
544 fp[ i ].x = FLOAT( x + xr * cos ( sa ) );
545 fp[ i ].y = FLOAT( y + yr * sin ( sa ) );
546
547 } // end for
548
549 if ( fXform ) _XFORMApplyf ( fp, n, &myXform );
550
551 i = 0;
552
553 if ( dwAFlags & ARCF_PIE ) {
554
555 myFlags &= ~EHDCF_JBEVL;
556 MoveToEx ( ROUNDL( fp[ 0 ].x ), ROUNDL( fp[ 0 ].y ), NULL );
557 LineTo ( ROUNDL( fp[ 1 ].x ), ROUNDL( fp[ 1 ].y ) );
558
559 ++i;
560
561 if ( i >= n ) goto end;
562
563 LineTo ( ROUNDL( fp[ i ].x ), ROUNDL( fp[ i ].y ) );
564
565 ++i;
566
567 } else {
568
569 MoveToEx ( ROUNDL( fp[ 1 ].x ), ROUNDL( fp[ 1 ].y ), NULL );
570 ++i;
571
572 } // end else
573
574 myFlags |= EHDCF_JBEVL;
575
576 for ( j = i - 1; i < n; ++i ) {
577
578 x = ROUNDL( fp[ i ].x );
579 y = ROUNDL( fp[ i ].y );
580
581 if ( x == ROUNDL( fp[ j ].x ) && y == ROUNDL( fp[ j ].y ) ) continue;
582
583 LineTo ( x, y );
584 j = i;
585
586 } // end for
587end:
588 if ( dwAFlags & ( ARCF_PIE | ARCF_CHORD ) || fabs ( oa ) == 6.28318 ) {
589
590 myFlags &= ~EHDCF_JBEVL;
591 ClosePath ();
592
593 } // end if
594
595 myFlags = dwFlags;
596 myA = pA;
597 myB = pB;
598 myClose = pClose;
599 myJoin = pJoin;
600 myCJoin = pCJoin;
601 myStart = pStart;
602 myPRlen = dwPRlen;
603 myPIndex = dwPIndex;
604
605} // end EHDC :: Arc
606
607void EHDC :: Polyarc (
608 int x, int y, int xr, int yr, double sa, double oa, BOOL fChord
609 ) {
610
611 int i = 0, n;
612 double ssa = sa, delta;
613 FPOINT fp[ 362 ];
614 BOOL fXform = ( myFlags & EHDCF_XFORM );
615
616 if ( oa > 6.28318 )
617
618 oa = 6.28318;
619
620 else if ( oa < -6.28318 )
621
622 oa = -6.28318;
623
624 n = abs ( ROUNDL( oa * 180.0 / 3.14159 ) );
625 delta = oa / n;
626
627 fp[ i ].x = ( FLOAT )x;
628 fp[ i++ ].y = ( FLOAT )y;
629 n += 2;
630
631 for ( ; i < n; ++i, sa += delta ) {
632
633 fp[ i ].x = FLOAT( x + xr * cos ( sa ) );
634 fp[ i ].y = FLOAT( y + yr * sin ( sa ) );
635
636 } // end for
637
638 if ( fXform ) _XFORMApplyf ( fp, n, &myXform );
639
640 i = 0;
641
642 HPEN hpo = SelectPen( myHDC, GetStockObject ( NULL_PEN ) );
643 HBRUSH hbo = SelectBrush( myHDC, myBrush ? myBrush : GetStockObject ( NULL_BRUSH ) );
644
645 BeginPath ( myHDC );
646
647 if ( !fChord ) {
648
649 ::MoveToEx (
650 myHDC,
651 ROUNDL( fp[ 0 ].x ), Y( ROUNDL( fp[ 0 ].y ) ), NULL
652 );
653 ::LineTo (
654 myHDC,
655 ROUNDL( fp[ 1 ].x ), Y( ROUNDL( fp[ 1 ].y ) )
656 );
657
658 ++i;
659
660 if ( i >= n ) goto end;
661
662 ::LineTo (
663 myHDC,
664 ROUNDL( fp[ i ].x ), Y( ROUNDL( fp[ i ].y ) )
665 );
666
667 } else {
668
669 ::MoveToEx (
670 myHDC,
671 ROUNDL( fp[ 1 ].x ), Y( ROUNDL( fp[ 1 ].y ) ), NULL
672 );
673 ++i;
674
675 } // end else
676
677 for ( ; i < n; ++i ) ::LineTo (
678 myHDC,
679 ROUNDL( fp[ i ].x ), Y( ROUNDL( fp[ i ].y ) )
680 );
681end:
682 CloseFigure ( myHDC );
683
684 EndPath ( myHDC );
685
686 FillPath ( myHDC );
687
688 SelectBrush( myHDC, hbo );
689 SelectPen( myHDC, hpo );
690
691 Arc ( x, y, xr, yr, ssa, oa, fChord ? ARCF_CHORD : ARCF_PIE );
692
693} // end EHDC :: Polyarc
694
695void EHDC :: SetPixel ( int x, int y, COLORREF c ) {
696
697 POINT p = { x, y };
698
699 if ( myFlags & EHDCF_XFORM ) _XFORMApply ( &p, 1, &myXform );
700
701 p.y = Y( p.y );
702
703 ::SetPixel ( myHDC, p.x, p.y, c );
704
705} // end EHDC :: SetPixel
706
707void EHDC :: SetTextColor ( COLORREF c ) {
708
709 LOGPEN lp;
710
711 GetObject ( myTextPen, sizeof ( LOGPEN ), &lp );
712
713 if ( lp.lopnColor != c ) {
714
715 LOGBRUSH lb = { BS_SOLID, c, 0 };
716
717 if ( myTextBrush != NULL ) DeleteBrush( myTextBrush );
718 if ( myTextPen != NULL ) DeletePen( myTextPen );
719
720 myTextPen = CreatePen ( PS_SOLID, 0, c );
721 myTextBrush = CreateBrushIndirect ( &lb );
722
723 } // end if
724
725} // end EHDC :: SetTextColor
726
727void EHDC :: SetTextAttrib ( COLORREF c, HFONT f, double slant, double hs, double vs ) {
728
729 SetTextColor ( c );
730
731 myTextFont = f;
732 myTextSlant = slant;
733 myTextHScale = hs;
734 myTextVScale = vs;
735
736} // end EHDC :: SetTextAttrib
737
738void EHDC :: ETextOut ( int x, int y, char* str, double angle, BOOL fOutline ) {
739
740 _ETextOut ( x, y, str, angle, fOutline );
741
742} // end EHDC :: TextOut
743
744void EHDC :: ETextOut ( int x, int y, wchar_t* str, double angle, BOOL fOutline ) {
745
746 _ETextOut ( x, y, str, angle, fOutline, TRUE );
747
748} // end EHDC :: TextOut
749
750void EHDC :: PolyTextOut (
751 int x, int y, char* str, double angle,
752 double margin, BOOL fOutline, BOOL fNofill, BOOL fNoframe
753 ) {
754
755 _PolyTextOut ( x, y, str, angle, margin, fOutline, FALSE, fNofill, fNoframe );
756
757} // end EHDC :: PolyTextOut
758
759void EHDC :: PolyTextOut (
760 int x, int y, wchar_t* str, double angle, double margin,
761 BOOL fOutline, BOOL fNofill, BOOL fNoframe
762 ) {
763
764 _PolyTextOut ( x, y, str, angle, margin, fOutline, TRUE, fNofill, fNoframe );
765
766} // end EHDC :: PolyTextOut
767
768void EHDC :: SetWorldTransform ( XFORM* xf ) {
769
770 if ( xf == NULL )
771
772 myFlags &= ~EHDCF_XFORM;
773
774 else {
775
776 myXform = *xf;
777 myFlags |= EHDCF_XFORM;
778
779 } // end else
780
781} // end EHDC :: SetWorldTransform
782
783void EHDC :: ModifyWorldTransform ( XFORM* xf, DWORD iMode ) {
784
785 XFORM rxf;
786 PXFORM pxfLeft;
787 PXFORM pxfRight;
788
789 if ( iMode == MWT_RIGHTMULTIPLY ) {
790
791 pxfLeft = &myXform;
792 pxfRight = xf;
793
794 } else if ( iMode == MWT_LEFTMULTIPLY ) {
795
796 pxfLeft = xf;
797 pxfRight = &myXform;
798
799 } else if ( iMode == MWT_IDENTITY ) {
800
801 myXform.eM11 = 1.0F; myXform.eM12 = 0.0F;
802 myXform.eM21 = 0.0F; myXform.eM22 = 1.0F;
803 myXform.eDx = 0.0F; myXform.eDy = 0.0F;
804
805 myFlags &= ~EHDCF_XFORM;
806
807 return;
808
809 } else return;
810
811 _XFORMultiply ( &rxf, pxfLeft, pxfRight );
812
813 myXform = rxf;
814 myFlags |= EHDCF_XFORM;
815
816} // end EHDC :: ModifyWorldTransform
817
818void EHDC :: Transform ( LPPOINT p, int n ) {
819
820 _XFORMApply ( p, n, &myXform );
821
822} // end TransformXY
823
824void EHDC :: ResetURect ( void ) {
825
826 myURect.left = LONG_MAX;
827 myURect.top = LONG_MAX;
828 myURect.right = LONG_MIN;
829 myURect.bottom = LONG_MIN;
830
831} // end EHDC :: ResetURect
832
833void EHDC :: GetURect ( LPRECT lpRect ) {
834
835 *lpRect = myURect;
836
837 if ( lpRect -> top < 0 ) lpRect -> top = 0;
838 if ( lpRect -> left < 0 ) lpRect -> left = 0;
839 if ( lpRect -> bottom > mySize.cy ) lpRect -> bottom = mySize.cy;
840 if ( lpRect -> right > mySize.cx ) lpRect -> right = mySize.cx;
841
842} // end EHDC :: GetURect
843
844void EHDC :: _Init ( void ) {
845
846 myTextPen = ( HPEN )GetStockObject ( WHITE_PEN );
847 myTextBrush = ( HBRUSH )GetStockObject ( WHITE_BRUSH );
848 myTextFont = NULL;
849 myTextPath = NULL;
850 myPPen = myTextPen;
851 myPBrush =
852 myBrush = myTextBrush;
853 myPStyle = NULL;
854 myTextBS =
855 myPBS =
856 myPNS = 0;
857 myFlags = 0;
858 myTextSlant = 0.0;
859 myTextHScale =
860 myTextVScale = 1.0;
861 myNDDA = 1024;
862 myDDA1 = ( PPOINT )HeapAlloc (
863 GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS,
864 sizeof ( POINT ) * myNDDA
865 );
866 myDDA2 = ( PPOINT )HeapAlloc (
867 GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS,
868 sizeof ( POINT ) * myNDDA
869 );
870 myIDDA = 0;
871
872 ModifyWorldTransform ( NULL, MWT_IDENTITY );
873 myFlags &= ~EHDCF_XFORM;
874
875} // end EHDC :: _Init
876
877void EHDC :: _DrawTo ( PPOINT p ) {
878
879 POINT ip[ 4 ];
880 double dx, dy, dxhw, dyhw, factor;
881
882 dx = ( double )( p -> x - myStart.x );
883 dy = ( double )( p -> y - myStart.y );
884
885 if ( dx == 0.0 && dy == 0.0 ) return;
886
887 factor = myPWidth / 2.0 / sqrt ( dx * dx + dy * dy );
888 dxhw = dy * factor;
889 dyhw = dx * factor;
890
891 ip[ 0 ].x = ROUNDL( myStart.x + dxhw );
892 ip[ 0 ].y = ROUNDL( myStart.y - dyhw );
893
894 ip[ 1 ].x = ROUNDL( p -> x + dxhw );
895 ip[ 1 ].y = ROUNDL( p -> y - dyhw );
896
897 ip[ 2 ].x = ROUNDL( p -> x - dxhw );
898 ip[ 2 ].y = ROUNDL( p -> y + dyhw );
899
900 ip[ 3 ].x = ROUNDL( myStart.x - dxhw );
901 ip[ 3 ].y = ROUNDL( myStart.y + dyhw );
902
903 Register ( ip, 4 );
904
905 ::Polygon ( myHDC, ip, 4 );
906
907 myA = myB;
908 myB = myStart;
909 myStart = *p;
910
911} // end EHDC :: _DrawTo
912
913void EHDC :: _Join ( void ) {
914
915 int np;
916 POINT p[ 4 ];
917 double r, ba, bc, dxba, dyba, dxbc, dybc,
918 s, sa, fc, xd, yd, xe, ye,
919 xf, yf, m1, m2, n1,
920 n2, rm1, rm2, rn1, rn2;
921
922 r = myPWidth / 2.0;
923 dxba = ( double )( myA.x - myB.x ); dyba = ( FLOAT )( myA.y - myB.y );
924 dxbc = ( double )( myStart.x - myB.x ); dybc = ( FLOAT )( myStart.y - myB.y );
925 ba = sqrt ( dxba * dxba + dyba * dyba );
926 bc = sqrt ( dxbc * dxbc + dybc * dybc );
927
928 if ( ba == 0.0 || bc == 0.0 ) return;
929
930 n1 = -dxba / ba; n2 = dyba / ba;
931 m1 = -dxbc / bc; m2 = dybc / bc;
932 s = m1 * n2 - n1 * m2;
933
934 if ( ( sa = fabs ( s ) ) < 0.001 ) return;
935
936 fc = r / sa;
937 xd = myB.x + fc * ( m1 + n1 );
938 yd = myB.y - fc * ( m2 + n2 );
939 rm1 = r * m1; rm2 = r * m2;
940 rn1 = r * n1; rn2 = r * n2;
941
942 if ( s > 0.0 ) {
943
944 xe = myB.x - rm2; ye = myB.y - rm1;
945 xf = myB.x + rn2; yf = myB.y + rn1;
946
947 } else if ( s < 0.0 ) {
948
949 xe = myB.x + rm2; ye = myB.y + rm1;
950 xf = myB.x - rn2; yf = myB.y - rn1;
951
952 } else return;
953
954 p[ 0 ] = myB;
955 p[ 1 ].x = ROUNDL( xf ); p[ 1 ].y = ROUNDL( yf );
956
957 if ( !( myFlags & EHDCF_JBEVL ) ) {
958
959 p[ 2 ].x = ROUNDL( xd ); p[ 2 ].y = ROUNDL( yd );
960 p[ 3 ].x = ROUNDL( xe ); p[ 3 ].y = ROUNDL( ye );
961 np = 4;
962
963 } else {
964
965 p[ 2 ].x = ROUNDL( xe ); p[ 2 ].y = ROUNDL( ye );
966 np = 3;
967
968 } // end else
969
970 Register ( p, np );
971#if 0
972 ::SetPixel ( myHDC, p[ 0 ].x, p[ 0 ].y, RGB( 255, 255, 255 ) );
973 ::SetPixel ( myHDC, p[ 1 ].x, p[ 1 ].y, RGB( 255, 255, 255 ) );
974 ::SetPixel ( myHDC, p[ 2 ].x, p[ 2 ].y, RGB( 255, 255, 255 ) );
975 ::SetPixel ( myHDC, p[ 3 ].x, p[ 3 ].y, RGB( 255, 255, 255 ) );
976#endif
977 HPEN hpo = SelectPen( myHDC, GetStockObject ( NULL_PEN ) );
978 ::Polygon ( myHDC, p, np );
979 SelectPen( myHDC, hpo );
980
981} // end EHDC :: _Join
982
983BOOL EHDC :: _DrawToEx ( PPOINT p ) {
984
985 DWORD i = 0, j, k;
986 DDAP ddap = { this };
987 POINT pp[ 4 ];
988 double dx, dy, dxhw, dyhw, factor;
989
990 dx = ( double )( p -> x - myStart.x );
991 dy = ( double )( p -> y - myStart.y );
992
993 if ( dx == 0.0 && dy == 0.0 ) return FALSE;
994
995 factor = myPWidth / 2.0 / sqrt ( dx * dx + dy * dy );
996 dxhw = dy * factor;
997 dyhw = dx * factor;
998
999 pp[ 0 ].x = ROUNDL( myStart.x + dxhw );
1000 pp[ 0 ].y = ROUNDL( myStart.y - dyhw );
1001
1002 pp[ 1 ].x = ROUNDL( myStart.x - dxhw );
1003 pp[ 1 ].y = ROUNDL( myStart.y + dyhw );
1004
1005 pp[ 2 ].x = ROUNDL( p -> x - dxhw );
1006 pp[ 2 ].y = ROUNDL( p -> y + dyhw );
1007
1008 pp[ 3 ].x = ROUNDL( p -> x + dxhw );
1009 pp[ 3 ].y = ROUNDL( p -> y - dyhw );
1010
1011 myIDDA = 0;
1012 myFlags &= ~EHDCF_DDAF;
1013 ddap.pp = myDDA1;
1014 LineDDA ( pp[ 0 ].x, pp[ 0 ].y, pp[ 3 ].x, pp[ 3 ].y, &___auxDDAF, ( LPARAM )&ddap );
1015 k = myIDDA;
1016 myIDDA = 0;
1017 myFlags &= ~EHDCF_DDAF;
1018 ddap.pp = myDDA2;
1019 LineDDA ( pp[ 1 ].x, pp[ 1 ].y, pp[ 2 ].x, pp[ 2 ].y, &___auxDDAF, ( LPARAM )&ddap );
1020 myIDDA = min( k, myIDDA );
1021 HPEN hpo = SelectPen( myHDC, GetStockObject ( NULL_PEN ) );
1022
302f96fb 1023 for(;;) {
7fd59977 1024
1025 if ( myPRlen == 0 ) {
1026
1027 myPRlen = myPStyle[ myPIndex++ ];
1028
1029 if ( myPIndex == myPNS ) myPIndex = 0;
1030
1031 } // end if
1032
1033 j = i;
1034
1035 while ( myPRlen != 0 && j < myIDDA ) ++j, --myPRlen;
1036
1037 if ( j == myIDDA ) {
1038
1039 myDDA1[ j ] = pp[ 3 ];
1040 myDDA2[ j ] = pp[ 2 ];
1041
1042 } // end if
1043
1044 if ( myFlags & EHDCF_PDRAW ) {
1045
1046 POINT p[ 4 ];
1047
1048 p[ 0 ] = myDDA1[ i ];
1049 p[ 1 ] = myDDA1[ j ];
1050 p[ 2 ] = myDDA2[ j ];
1051 p[ 3 ] = myDDA2[ i ];
1052
1053 Register ( p, 4 );
1054 ::Polygon ( myHDC, p, 4 );
1055
1056 } // end if
1057
1058 if ( myPRlen == 0 )
1059
1060 myFlags ^= EHDCF_PDRAW;
1061
1062 else break;
1063
1064 i = j;
1065
1066 if ( j >= myIDDA ) break;
1067
1068 } // end while
1069
1070 SelectPen( myHDC, hpo );
1071
1072 if ( myPRlen == 0 ) myFlags |= EHDCF_NJOIN;
1073
1074 myA = myB;
1075 myB = myStart;
1076 myStart = *p;
1077
1078 return TRUE;
1079
1080} // end EHDC :: _DrawToEx
1081
1082void EHDC :: _LineTo ( PPOINT p ) {
1083
1084 DWORD i = 0;
1085 DDAP ddap = { this };
1086
1087 Register ( p, 1 );
1088
1089 myIDDA = 0;
1090 ddap.pp = myDDA1;
1091 LineDDA ( myStart.x, myStart.y, p -> x, p -> y, &___auxDDAF, ( LPARAM )&ddap );
1092
302f96fb 1093 for(;;) {
7fd59977 1094
1095 if ( myPRlen == 0 ) {
1096
1097 myPRlen = myPStyle[ myPIndex++ ];
1098
1099 if ( myPIndex == myPNS ) myPIndex = 0;
1100
1101 } // end if
1102
1103 if ( myFlags & EHDCF_PDRAW ) ::MoveToEx ( myHDC, myDDA1[ i ].x, myDDA1[ i ].y, NULL );
1104
1105 while ( myPRlen != 0 && i < myIDDA ) ++i, --myPRlen;
1106
1107 if ( i == myIDDA ) myDDA1[ i ] = *p;
1108
1109 if ( myFlags & EHDCF_PDRAW )
1110
1111 ::LineTo ( myHDC, myDDA1[ i ].x, myDDA1[ i ].y );
1112
1113 if ( myPRlen == 0 )
1114
1115 myFlags ^= EHDCF_PDRAW;
1116
1117 else break;
1118
1119 } // end while
1120
1121 myStart = *p;
1122
1123} // end EHDC :: _LineTo
1124
1125void EHDC :: _ETextOut ( int x, int y, void* str, double angle, BOOL fOutline, BOOL fWide ) {
1126#if 1
1127 int i;
1128 DWORD dwLen;
1129 HPEN hpo;
1130 HBRUSH hbo;
1131 HFONT hfo;
1132 XFORM lXfm, rXfm, xfm;
1133 PXFORM pXfm;
1134 SIZE sz;
1135 double tanVal;
1136 double sinVal;
1137 double cosVal;
1138 LPPOINT lp;
1139
1140 angle = -angle;
1141 tanVal = tan ( myTextSlant ) * myTextVScale;
1142 sinVal = sin ( angle );
1143 cosVal = cos ( angle );
1144
1145 if ( !( myFlags & EHDCF_TPATH ) ) {
1146
1147 hfo = SelectFont( myHDC, myTextFont );
1148
1149 i = myTextNP = _TextPath (
1150 myHDC, 0, 0, str, NULL, NULL, 0, &sz, fWide
1151 );
1152
1153 SelectFont( myHDC, hfo );
1154
1155 if ( i <= 0 ) return;
1156
1157 if ( myTextBS < myTextNP ) {
1158
1159 dwLen = sizeof ( POINT ) * myTextNP + sizeof ( BYTE ) * myTextNP;
1160
1161 if ( myTextPath == NULL )
1162
1163 myTextPath = ( LPPOINT )HeapAlloc (
1164 GetProcessHeap (),
1165 HEAP_GENERATE_EXCEPTIONS, dwLen
1166 );
1167
1168 else
1169
1170 myTextPath = ( LPPOINT )HeapReAlloc (
1171 GetProcessHeap (),
1172 HEAP_GENERATE_EXCEPTIONS,
1173 myTextPath, dwLen
1174 );
1175
1176 myTextBS = myTextNP;
1177
1178 } // end if
1179
1180 myTextType = ( PBYTE )( myTextPath + myTextNP );
1181
1182 _TextPath ( myHDC, 0, 0, str, myTextPath, myTextType, myTextNP, NULL, fWide );
1183
1184 lp = myTextPath;
1185
1186 while ( i-- ) {
1187
1188 lp -> y -= sz.cy;
1189 ++lp;
1190
1191 } // end while
1192
1193 } // end if
1194
1195 lXfm.eM11 = ( FLOAT )myTextHScale; lXfm.eM21 = ( FLOAT )-tanVal;
1196 lXfm.eM12 = 0.0F; lXfm.eM22 = ( FLOAT )myTextVScale;
1197 lXfm.eDx = 0.0F;
1198 lXfm.eDy = 0.0F;
1199
1200 rXfm.eM11 = ( FLOAT ) cosVal; rXfm.eM12 = ( FLOAT )sinVal;
1201 rXfm.eM21 = ( FLOAT )-sinVal; rXfm.eM22 = ( FLOAT )cosVal;
1202 rXfm.eDx = 0.0F;
1203 rXfm.eDy = 0.0F;
1204 _XFORMultiply ( &xfm, &lXfm, &rXfm );
1205
1206 rXfm.eM11 = 1.0F; rXfm.eM21 = 0.0F;
1207 rXfm.eM12 = 0.0F; rXfm.eM22 = -1.0F;
1208 rXfm.eDx = ( FLOAT )x;
1209 rXfm.eDy = ( FLOAT )y;
1210 _XFORMultiply ( &lXfm, &xfm, &rXfm );
1211
1212 if ( myFlags & EHDCF_XFORM ) {
1213
1214 _XFORMultiply ( &xfm, &lXfm, &myXform );
1215 pXfm = &xfm;
1216
1217 } else pXfm = &lXfm;
1218
1219 _XFORMApply ( myTextPath, myTextNP, pXfm );
1220
1221 i = myTextNP;
1222 lp = myTextPath;
1223
1224 while ( i-- ) lp -> y = Y( lp -> y ), ++lp;
1225
1226 hpo = SelectPen( myHDC, myTextPen );
1227
1228 if ( !fOutline ) hbo = SelectBrush( myHDC, myTextBrush );
1229
1230 if ( !( myFlags & EHDCF_TREG ) ) Register ( myTextPath, myTextNP );
1231
1232 BeginPath ( myHDC );
1233 _RenderPath ( myHDC, myTextPath, myTextType, myTextNP );
1234 EndPath ( myHDC );
1235
1236 if ( !fOutline ) {
1237
1238 FillPath ( myHDC );
1239 SelectBrush( myHDC, hbo );
1240
1241 } else StrokePath ( myHDC );
1242
1243 SelectPen( myHDC, hpo );
1244#else
1245 int i;
1246 DWORD dwLen;
1247 HPEN hpo;
1248 HBRUSH hbo;
1249 HFONT hfo;
1250 XFORM lXfm, rXfm, xfm;
1251 PXFORM pXfm;
1252 SIZE sz;
1253 double tanVal;
1254 double sinVal;
1255 double cosVal;
1256 LPPOINT lp;
1257 BOOL fNew = FALSE;
1258
1259 angle = -angle;
1260 tanVal = tan ( myTextSlant );
1261 sinVal = sin ( angle );
1262 cosVal = cos ( angle );
1263
1264 if ( !( myFlags & EHDCF_TPATH ) ) {
1265
1266 hfo = SelectFont( myHDC, myTextFont );
1267
1268 if ( myTextVScale != 1.0 || myTextHScale != 1.0 ) {
1269
1270 LOGFONT lf;
1271 TEXTMETRIC tm;
1272
1273 GetObject ( myTextFont, sizeof ( LOGFONT ), &lf );
1274 GetTextMetrics ( myHDC, &tm );
1275
1276 lf.lfHeight = ROUNDL( lf.lfHeight * myTextVScale );
1277 lf.lfWidth = ROUNDL( lf.lfWidth * myTextHScale );
1278
1279 lf.lfQuality = DRAFT_QUALITY;
1280
1281 if ( lf.lfWidth == 0 )
1282
1283 lf.lfWidth = ROUNDL( tm.tmAveCharWidth * myTextHScale );
1284
1285 SelectFont( myHDC, hfo );
1286
1287 hfo = SelectFont( myHDC, CreateFontIndirect ( &lf ) );
1288 fNew = TRUE;
1289
1290 } // end if
1291
1292 i = myTextNP = _TextPath (
1293 myHDC, 0, 0, str, NULL, NULL, 0, &sz, fWide
1294 );
1295
1296 hfo = SelectFont( myHDC, hfo );
1297
1298 if ( fNew ) DeleteFont( hfo );
1299
1300 if ( i <= 0 ) return;
1301
1302 if ( myTextBS < myTextNP ) {
1303
1304 dwLen = sizeof ( POINT ) * myTextNP + sizeof ( BYTE ) * myTextNP;
1305
1306 if ( myTextPath == NULL )
1307
1308 myTextPath = ( LPPOINT )HeapAlloc (
1309 GetProcessHeap (),
1310 HEAP_GENERATE_EXCEPTIONS, dwLen
1311 );
1312
1313 else
1314
1315 myTextPath = ( LPPOINT )HeapReAlloc (
1316 GetProcessHeap (),
1317 HEAP_GENERATE_EXCEPTIONS,
1318 myTextPath, dwLen
1319 );
1320
1321 myTextBS = myTextNP;
1322
1323 } // end if
1324
1325 myTextType = ( PBYTE )( myTextPath + myTextNP );
1326
1327 _TextPath ( myHDC, 0, 0, str, myTextPath, myTextType, myTextNP, NULL, fWide );
1328
1329 lp = myTextPath;
1330
1331 while ( i-- ) {
1332
1333 lp -> y -= sz.cy;
1334 ++lp;
1335
1336 } // end while
1337
1338 } // end if
1339
1340 lXfm.eM11 = 1.0F; lXfm.eM21 = ( FLOAT )-tanVal;
1341 lXfm.eM12 = 0.0F; lXfm.eM22 = 1.0F;
1342 lXfm.eDx = 0.0F;
1343 lXfm.eDy = 0.0F;
1344
1345 rXfm.eM11 = ( FLOAT ) cosVal; rXfm.eM12 = ( FLOAT )sinVal;
1346 rXfm.eM21 = ( FLOAT )-sinVal; rXfm.eM22 = ( FLOAT )cosVal;
1347 rXfm.eDx = 0.0F;
1348 rXfm.eDy = 0.0F;
1349 _XFORMultiply ( &xfm, &lXfm, &rXfm );
1350
1351 rXfm.eM11 = 1.0F; rXfm.eM21 = 0.0F;
1352 rXfm.eM12 = 0.0F; rXfm.eM22 = -1.0F;
1353 rXfm.eDx = ( FLOAT )x;
1354 rXfm.eDy = ( FLOAT )y;
1355 _XFORMultiply ( &lXfm, &xfm, &rXfm );
1356
1357 if ( myFlags & EHDCF_XFORM ) {
1358
1359 _XFORMultiply ( &xfm, &lXfm, &myXform );
1360 pXfm = &xfm;
1361
1362 } else pXfm = &lXfm;
1363
1364 _XFORMApply ( myTextPath, myTextNP, pXfm );
1365
1366 i = myTextNP;
1367 lp = myTextPath;
1368
1369 while ( i-- ) lp -> y = Y( lp -> y ), ++lp;
1370
1371 hpo = SelectPen( myHDC, myTextPen );
1372
1373 if ( !fOutline ) hbo = SelectBrush( myHDC, myTextBrush );
1374
1375 if ( !( myFlags & EHDCF_TREG ) ) Register ( myTextPath, myTextNP );
1376
1377 BeginPath ( myHDC );
1378 _RenderPath ( myHDC, myTextPath, myTextType, myTextNP );
1379 EndPath ( myHDC );
1380
1381 if ( !fOutline ) {
1382
1383 FillPath ( myHDC );
1384 SelectBrush( myHDC, hbo );
1385
1386 } else StrokePath ( myHDC );
1387
1388 SelectPen( myHDC, hpo );
1389#endif
1390} // end EHDC :: _ETextOut
1391
1392void EHDC :: _PolyTextOut (
1393 int x, int y, void* str, double angle, double margin,
1394 BOOL fOutline, BOOL fWide, BOOL fNofill, BOOL fNoframe
1395 ) {
1396
1397 POINT p[ 4 ];
1398 XFORM lXfm, xfm;
1399 PXFORM pXfm;
1400 SIZE sz;
1401 HFONT hfo;
1402 DWORD dwFlags;
1403 TEXTMETRIC tm;
1404 double sinVal = sin ( angle );
1405 double cosVal = cos ( angle );
1406 double tanVal = -tan ( myTextSlant );
1407 double height;
1408
1409 hfo = SelectFont( myHDC, myTextFont );
1410
1411 if ( !fWide )
1412
1413 GetTextExtentPoint32A (
1414 myHDC, ( char* )str, lstrlenA ( ( char* )str ), &sz
1415 );
1416
1417 else
1418
1419 GetTextExtentPoint32W (
1420 myHDC, ( wchar_t* )str, lstrlenW ( ( wchar_t* )str ), &sz
1421 );
1422
1423 GetTextMetrics ( myHDC, &tm );
1424 SelectFont( myHDC, hfo );
1425
1426 sz.cy -= tm.tmInternalLeading;
1427
1428 p[ 0 ].x = 0;
1429 p[ 0 ].y = ROUNDL( sz.cy * myTextVScale );
1430 p[ 1 ].x = ROUNDL( sz.cx * myTextHScale );
1431 p[ 1 ].y = p[ 0 ].y;
1432 p[ 2 ].x = p[ 1 ].x;
1433 p[ 2 ].y = 0;
1434 p[ 3 ].x = 0;
1435 p[ 3 ].y = 0;
1436
1437 tanVal *= p[ 1 ].y;
1438
1439 if ( myTextSlant < 0.0F ) {
1440
1441 p[ 0 ].x -= ( LONG )tanVal;
1442 p[ 3 ].x -= ( LONG )tanVal;
1443
1444 } else {
1445
1446 p[ 1 ].x -= ( LONG )tanVal;
1447 p[ 2 ].x -= ( LONG )tanVal;
1448
1449 } /* end else */
1450
1451 height = ROUNDL( p[ 0 ].y * margin / 2.0 );
1452
1453 p[ 0 ].x = ROUNDL( p[ 0 ].x - height );
1454 p[ 0 ].y = ROUNDL( p[ 0 ].y + height );
1455 p[ 1 ].x = ROUNDL( p[ 1 ].x + height );
1456 p[ 1 ].y = ROUNDL( p[ 1 ].y + height );
1457 p[ 2 ].x = ROUNDL( p[ 2 ].x + height );
1458 p[ 2 ].y = ROUNDL( p[ 2 ].y - height );
1459 p[ 3 ].x = ROUNDL( p[ 3 ].x - height );
1460 p[ 3 ].y = ROUNDL( p[ 3 ].y - height );
1461
1462 lXfm.eM11 = ( FLOAT ) cosVal; lXfm.eM12 = ( FLOAT )sinVal;
1463 lXfm.eM21 = ( FLOAT )-sinVal; lXfm.eM22 = ( FLOAT )cosVal;
1464 lXfm.eDx = ( FLOAT )x;
1465 lXfm.eDy = ( FLOAT )y;
1466
1467 if ( myFlags & EHDCF_XFORM ) {
1468
1469 _XFORMultiply ( &xfm, &lXfm, &myXform );
1470 pXfm = &xfm;
1471
1472 } else pXfm = &lXfm;
1473
1474 _XFORMApply ( p, 4, pXfm );
1475
1476 dwFlags = ( myFlags & EHDCF_XFORM );
1477 myFlags &= ~EHDCF_XFORM;
1478
1479 if ( fNofill )
1480
1481 Polyline ( p, 4, TRUE );
1482
1483 else
1484
1485 Polygon ( p, 4, fNoframe ? POLYF_NOEDGE : 0 );
1486
1487 myFlags |= dwFlags;
1488
1489 _ETextOut ( x, y, str, angle, fOutline, fWide );
1490
1491} // end EHDC :: _PolyTextOut
1492
1493void EHDC :: Register ( LPPOINT lpPts, int nPts ) {
1494
1495 while ( nPts-- ) {
1496
1497 if ( lpPts -> x < myURect.left )
1498
1499 myURect.left = lpPts -> x - 1;
1500
1501 else if ( lpPts -> x > myURect.right )
1502
1503 myURect.right = lpPts -> x + 2;
1504
1505 if ( lpPts -> y < myURect.top )
1506
1507 myURect.top = lpPts -> y - 1;
1508
1509 else if ( lpPts -> y > myURect.bottom )
1510
1511 myURect.bottom = lpPts -> y + 2;
1512
1513 ++lpPts;
1514
1515 } // end while
1516
1517} // end EHDC :: _Register
1518//+++//
1519//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1520//+++//
1521static void WINAPI _XFORMultiply ( PXFORM res, PXFORM left, PXFORM right ) {
1522
1523 res -> eM11 = left -> eM11 * right -> eM11 + left -> eM12 * right -> eM21;
1524 res -> eM12 = left -> eM11 * right -> eM12 + left -> eM12 * right -> eM22;
1525 res -> eDx = left -> eDx * right -> eM11 + left -> eDy * right -> eM21 + right -> eDx;
1526
1527 res -> eM21 = left -> eM21 * right -> eM11 + left -> eM22 * right -> eM21;
1528 res -> eM22 = left -> eM21 * right -> eM12 + left -> eM22 * right -> eM22;
1529 res -> eDy = left -> eDx * right -> eM12 + left -> eDy * right -> eM22 + right -> eDy;
1530
1531} /* end _XFORMultiply */
1532
1533static void WINAPI _XFORMApply ( PPOINT pp, int n, PXFORM xf ) {
1534
1535 int i;
1536 double dx, dy;
1537
1538 for ( i = 0; i < n; ++i ) {
1539
1540 dx = pp[ i ].x * xf -> eM11 + pp[ i ].y * xf -> eM21 + xf -> eDx;
1541 dy = pp[ i ].x * xf -> eM12 + pp[ i ].y * xf -> eM22 + xf -> eDy;
1542
1543 pp[ i ].x = ROUNDL( dx );
1544 pp[ i ].y = ROUNDL( dy );
1545
1546 } /* end for */
1547
1548} /* end _XFORMApply */
1549
1550static void WINAPI _XFORMApplyf ( PFPOINT pp, int n, PXFORM xf ) {
1551
1552 int i;
1553 double dx, dy;
1554
1555 for ( i = 0; i < n; ++i ) {
1556
1557 dx = pp[ i ].x * xf -> eM11 + pp[ i ].y * xf -> eM21 + xf -> eDx;
1558 dy = pp[ i ].x * xf -> eM12 + pp[ i ].y * xf -> eM22 + xf -> eDy;
1559
1560 pp[ i ].x = ( FLOAT )dx;
1561 pp[ i ].y = ( FLOAT )dy;
1562
1563 } /* end for */
1564
1565} /* end _XFORMApply */
1566
1567static void WINAPI _RenderPath ( HDC hdc, LPPOINT lpPts, PBYTE lpType, int nPts ) {
1568
1569 LPPOINT pp;
1570
1571 for ( int i = 0; i < nPts; ++i ) {
1572
1573 switch ( lpType[ i ] ) {
1574
1575 case PT_MOVETO:
1576
1577 MoveToEx ( hdc, lpPts[ i ].x, lpPts[ i ].y, NULL );
1578 pp = &lpPts[ i ];
1579
1580 continue;
1581
1582 case PT_LINETO:
1583 case PT_LINETO | PT_CLOSEFIGURE:
1584
1585 LineTo ( hdc, lpPts[ i ].x, lpPts[ i ].y );
1586 goto testClose;
1587
1588 case PT_BEZIERTO:
1589 case PT_BEZIERTO | PT_CLOSEFIGURE:
1590
1591 PolyBezierTo ( hdc, &lpPts[ i ], 3 );
1592
1593 i += 2;
1594testClose:
1595 if ( lpType[ i ] & PT_CLOSEFIGURE ) LineTo ( hdc, pp -> x, pp -> y );
1596
1597 } /* end switch */
1598
1599 } /* end for */
1600
1601} /* end _RenderPath */
1602
1603static int WINAPI _TextPath (
1604 HDC hdc, int x, int y, void* str, LPPOINT lpPts, PBYTE lpType,
1605 int nPts, PSIZE pSz, BOOL fWide
1606 ) {
1607
1608 int retVal;
1609
1610 if ( lpPts == NULL ) {
1611
1612 int bmo = SetBkMode ( hdc, TRANSPARENT );
1613
1614 BeginPath ( hdc );
1615
1616 if ( !fWide )
1617
1618 TextOutA ( hdc, x, y, ( char* )str, lstrlenA ( ( char* )str ) );
1619
1620 else
1621
1622 TextOutW ( hdc, x, y, ( wchar_t* )str, lstrlenW ( ( wchar_t* )str ) );
1623
1624 EndPath ( hdc );
1625
1626 SetBkMode ( hdc, bmo );
1627
1628 } /* end if */
1629
1630 retVal = GetPath ( hdc, lpPts, lpType, nPts );
1631
1632 if ( pSz != NULL )
1633
1634 if ( !fWide )
1635
1636 GetTextExtentPoint32A ( hdc, ( char* )str, lstrlenA ( ( char* )str ), pSz );
1637
1638 else
1639
1640 GetTextExtentPoint32W ( hdc, ( wchar_t* )str, lstrlenW ( ( wchar_t* )str ), pSz );
1641
1642 return retVal;
1643
1644} /* end _TextPath */
1645
1646VOID CALLBACK ___auxDDAF ( int x, int y, LPARAM lpParam ) {
1647
1648 PDDAP p = ( PDDAP )lpParam;
1649
1650 p -> pp[ p -> _this -> myIDDA ].x = x;
1651 p -> pp[ p -> _this -> myIDDA++ ].y = y;
1652
1653 if ( p -> _this -> myIDDA >= p -> _this -> myNDDA ) {
1654
1655 p -> _this -> myDDA1 = ( PPOINT )HeapReAlloc (
1656 GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS,
1657 p -> _this -> myDDA1, p -> _this -> myNDDA <<= 1
1658 );
1659 p -> _this -> myDDA2 = ( PPOINT )HeapReAlloc (
1660 GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS,
1661 p -> _this -> myDDA2, p -> _this -> myNDDA <<= 1
1662 );
1663
1664 } // end if
1665
1666} // end ___auxDDAF
1667//+++//
1668//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//