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 windows.h first to have all definitions available |
22 | #include <windows.h> |
23 | #include <windowsx.h> |
24 | |
25 | #include <WNT_ImageManager.ixx> |
26 | |
27 | #include <WNT_Image.hxx> |
28 | #include <WNT_GraphicDevice.hxx> |
29 | |
30 | #include <WNT_Bitmap.h> |
31 | |
7fd59977 |
32 | #define TRASH_SIZE 8 |
33 | |
34 | #define PWND ( ( WNT_WindowPtr )myWindow ) |
35 | |
36 | HBITMAP LoadImageFromFile ( Handle( WNT_GraphicDevice )&, char*, HDC = NULL ); |
37 | int SaveWindowToFile ( |
38 | Handle( WNT_GraphicDevice )&, HWND, char*, int, int, int, int |
39 | ); |
40 | int SaveBitmapToFile ( |
41 | Handle( WNT_GraphicDevice )&, HBITMAP, char*, int, int, int, int |
42 | ); |
43 | void SetOutputFormat ( WNT_TypeOfImage ); |
44 | //***// |
45 | //***************************** Constructor ******************************// |
46 | //***// |
47 | WNT_ImageManager :: WNT_ImageManager ( const WNT_WindowPtr& aWindow ) { |
48 | |
49 | myWindow = aWindow; |
50 | myLastIndex = 0; |
51 | |
52 | } // end constructor |
53 | //***// |
54 | //******************************* Destroy ********************************// |
55 | //***// |
56 | void WNT_ImageManager :: Destroy () { |
57 | |
58 | |
59 | } // end WNT_ImageManager :: Destroy |
60 | //***// |
61 | //******************************* SetFormat ******************************// |
62 | //***// |
63 | void WNT_ImageManager :: SetFormat ( const WNT_TypeOfImage aFormat ) { |
64 | |
65 | myFormat = aFormat; |
66 | SetOutputFormat ( aFormat ); |
67 | |
68 | } // end WNT_ImageManager :: SetFormat |
69 | //***// |
70 | //********************************** Load ********************************// |
71 | //***// |
72 | Standard_Integer WNT_ImageManager :: Load ( const Standard_CString aFileName ) { |
73 | |
74 | Handle( WNT_Image ) image; |
75 | Standard_Integer i, iHCode, len, retVal = 0; |
76 | HBITMAP hBmp; |
77 | |
78 | Handle( WNT_GraphicDevice ) gDev = Handle( WNT_GraphicDevice ) :: |
79 | DownCast ( PWND -> GraphicDevice () ); |
80 | |
81 | iHCode = StringHashCode ( aFileName ); |
82 | |
83 | if ( myLastIndex && myLastImage -> myHashCode == iHCode ) return myLastIndex; |
84 | |
85 | for ( i = 1; i <= myTrash.Length (); ++i ) |
86 | |
87 | if ( myTrash.Value ( i ) -> myHashCode == iHCode ) { |
88 | |
89 | myLastImage = myTrash.Value ( i ); |
90 | retVal = -i; |
91 | |
92 | goto end; |
93 | |
94 | } /* end if */ |
95 | |
96 | len = myImages.Length (); |
97 | |
98 | for ( i = 1; i <= len; ++i ) |
99 | |
100 | if ( myImages.Value ( i ) -> myHashCode == iHCode ) { |
101 | |
102 | myLastImage = myImages.Value ( i ); |
103 | retVal = i; |
104 | |
105 | goto end; |
106 | |
107 | } // end if |
108 | |
109 | hBmp = LoadImageFromFile ( gDev,(Standard_PCharacter) aFileName ); |
110 | |
111 | if ( hBmp ) { |
112 | |
113 | myLastImage = new WNT_Image ( hBmp, iHCode ); |
114 | myImages.Append ( myLastImage ); |
115 | retVal = myImages.Length (); |
116 | |
117 | } // end if |
118 | end: |
119 | return myLastIndex = retVal; |
120 | |
121 | } // end WNT_ImageManager :: Load |
122 | //***// |
123 | //********************************** Save ********************************// |
124 | //***// |
125 | Standard_Boolean WNT_ImageManager :: Save ( |
126 | const Standard_CString aFileName, |
127 | const Standard_Integer aX, |
128 | const Standard_Integer aY, |
129 | const Standard_Integer aWidth, |
130 | const Standard_Integer aHeight |
131 | ) const { |
132 | |
133 | Standard_Boolean retVal; |
134 | |
135 | Handle( WNT_GraphicDevice ) gDev = Handle( WNT_GraphicDevice ) :: |
136 | DownCast ( PWND -> GraphicDevice () ); |
137 | |
138 | retVal = SaveWindowToFile ( |
139 | gDev, ( HWND )( PWND -> HWindow () ), |
140 | (Standard_PCharacter) aFileName, aX, aY, aWidth, aHeight |
141 | ); |
142 | |
143 | return retVal; |
144 | |
145 | } // end WNT_ImageManager :: Save |
146 | //***// |
147 | //****************************** SaveBuffer ******************************// |
148 | //***// |
149 | Standard_Boolean WNT_ImageManager :: SaveBuffer ( |
150 | const Standard_CString aFileName, |
151 | const Standard_Integer aX, |
152 | const Standard_Integer aY, |
153 | const Standard_Integer aWidth, |
154 | const Standard_Integer aHeight |
155 | ) const { |
156 | |
157 | Standard_Boolean retVal; |
158 | Handle( WNT_GraphicDevice ) gDev = Handle( WNT_GraphicDevice ) :: |
159 | DownCast ( PWND -> GraphicDevice () ); |
160 | |
161 | retVal = SaveBitmapToFile ( |
162 | gDev, ( HBITMAP )( PWND -> HPixmap () ), |
163 | (Standard_PCharacter)aFileName, aX, aY, aWidth, aHeight |
164 | ); |
165 | |
166 | return retVal; |
167 | |
168 | } // end WNT_ImageManager :: SaveBuffer |
169 | //***// |
170 | //********************************** Draw ********************************// |
171 | //***// |
172 | void WNT_ImageManager :: Draw ( |
173 | const Standard_Integer anIndex, |
174 | const Standard_Integer Xc, |
175 | const Standard_Integer Yc, |
176 | const Standard_Integer aWidth, |
177 | const Standard_Integer aHeight, |
178 | const Standard_Real anAngle |
179 | ) { |
180 | |
181 | HDC hDC, hDCmemSrc, hDCmemDst = 0; |
182 | HPALETTE hPal, hOldPal; |
183 | Standard_Integer iw, ih; |
184 | |
185 | if ( myLastIndex != anIndex ) { |
186 | |
187 | myLastIndex = anIndex; |
188 | myLastImage = anIndex < 0 ? myTrash.Value ( -anIndex ) : myImages.Value ( anIndex ); |
189 | |
190 | } // end if |
191 | |
192 | Handle( WNT_GraphicDevice ) gDev = Handle( WNT_GraphicDevice ) :: |
193 | DownCast ( PWND -> GraphicDevice () ); |
194 | |
195 | Dim ( anIndex, iw, ih ); |
196 | |
197 | hDC = GetDC ( ( HWND )( PWND -> HWindow () ) ); |
198 | |
199 | if ( gDev -> IsPaletteDevice () ) { |
200 | |
201 | hOldPal = SelectPalette ( |
202 | hDC, hPal = ( HPALETTE )( gDev -> HPalette () ), FALSE |
203 | ); |
204 | |
205 | if ( RealizePalette ( hDC ) ) |
206 | |
207 | UpdateColors ( hDC ); |
208 | |
209 | } // end if |
210 | |
211 | if ( PWND -> DoubleBuffer () ) { |
212 | |
213 | hDCmemDst = CreateCompatibleDC ( hDC ); |
214 | SelectBitmap ( hDCmemDst, PWND -> HPixmap () ); |
215 | |
216 | } else |
217 | |
218 | hDCmemDst = hDC; |
219 | |
220 | hDCmemSrc = CreateCompatibleDC ( hDC ); |
221 | SetStretchBltMode ( hDCmemDst, COLORONCOLOR ); |
222 | |
223 | SelectBitmap ( |
224 | hDCmemSrc, ( ( PWNT_Bitmap )myLastImage -> myImage ) -> hBmp |
225 | ); |
226 | |
227 | if ( aWidth == iw && aHeight == ih && anAngle == 0.0F ) |
228 | |
229 | BitBlt ( |
230 | hDCmemDst, Xc - aWidth / 2 - ( aWidth & 1 ), |
231 | Yc - aHeight / 2, aWidth, aHeight, |
232 | hDCmemSrc, 0, 0, SRCCOPY |
233 | ); |
234 | |
235 | else if ( anAngle == 0.0F ) |
236 | |
237 | StretchBlt ( |
238 | hDCmemDst, Xc - aWidth / 2, |
239 | Yc - aHeight / 2 + ( aHeight & 1 ), aWidth, aHeight, |
240 | hDCmemSrc, 0, 0, iw, ih, SRCCOPY |
241 | ); |
242 | |
243 | else { |
244 | |
245 | XFORM x; |
246 | POINT pivot; |
247 | POINT pts[ 3 ]; |
248 | double sinVal, cosVal, angle; |
249 | |
250 | SetGraphicsMode ( hDCmemDst, GM_ADVANCED ); |
251 | |
252 | angle = ( double )anAngle * ( M_PI / 180. ); |
253 | cosVal = Cos ( angle ); |
254 | sinVal = Sin ( angle ); |
255 | |
256 | pts[ 0 ].x = Xc - aWidth / 2; |
257 | pts[ 0 ].y = Yc - aHeight / 2 + ( aHeight & 1 ); |
258 | |
259 | pts[ 1 ].x = Xc + aWidth / 2; |
260 | pts[ 1 ].y = pts[ 0 ].y; |
261 | |
262 | pts[ 2 ].x = pts[ 0 ].x; |
263 | pts[ 2 ].y = Yc + aHeight / 2 + ( aHeight & 1 ); |
264 | |
265 | pivot.x = ( pts[ 1 ].x + pts[ 2 ].x ) / 2; |
266 | pivot.y = ( pts[ 1 ].y + pts[ 2 ].y ) / 2; |
267 | |
268 | x.eM11 = 1.0F; x.eM12 = 0.0F; |
269 | x.eM21 = 0.0F; x.eM22 = 1.0F; |
270 | x.eDx = ( float )-pivot.x; |
271 | x.eDy = ( float )-pivot.y; |
272 | ModifyWorldTransform ( hDCmemDst, &x, MWT_RIGHTMULTIPLY ); |
273 | |
274 | x.eM11 = ( float )cosVal; x.eM12 = ( float )-sinVal; |
275 | x.eM21 = ( float )sinVal; x.eM22 = ( float ) cosVal; |
276 | x.eDx = 0.0F; |
277 | x.eDy = 0.0F; |
278 | ModifyWorldTransform ( hDCmemDst, &x, MWT_RIGHTMULTIPLY ); |
279 | |
280 | x.eM11 = 1.0F; x.eM12 = 0.0F; |
281 | x.eM21 = 0.0F; x.eM22 = 1.0F; |
282 | x.eDx = ( float )pivot.x; |
283 | x.eDy = ( float )pivot.y; |
284 | ModifyWorldTransform ( hDCmemDst, &x, MWT_RIGHTMULTIPLY ); |
285 | |
286 | PlgBlt ( hDCmemDst, pts, hDCmemSrc, 0, 0, iw, ih, NULL, 0, 0 ); |
287 | |
288 | } // end else |
289 | |
290 | DeleteDC ( hDCmemSrc ); |
291 | |
292 | if ( gDev -> IsPaletteDevice () ) |
293 | |
294 | SelectPalette ( hDC, hOldPal, FALSE ); |
295 | |
296 | if ( PWND -> DoubleBuffer () ) |
297 | |
298 | DeleteDC ( hDCmemDst ); |
299 | |
300 | ReleaseDC ( ( HWND )( PWND -> HWindow () ), hDC ); |
301 | |
302 | } // end WNT_ImageManager :: Draw |
303 | //***// |
304 | //********************************** Scale *******************************// |
305 | //***// |
306 | Aspect_Handle WNT_ImageManager :: Scale ( |
307 | const Standard_Integer anIndex, |
308 | const Standard_Real aScaleX, |
309 | const Standard_Real aScaleY, |
310 | const Standard_Boolean aReplace |
311 | ) { |
312 | |
313 | Standard_Integer iw, ih, iNw, iNh; |
314 | HDC hDCmemSrc, hDCmemDst, hDC; |
315 | HPALETTE hOldPal = NULL; |
316 | HBITMAP hBitmap, hOldBitmap, hBmp; |
317 | |
318 | if ( myLastIndex != anIndex ) { |
319 | |
320 | myLastIndex = anIndex; |
321 | myLastImage = anIndex < 0 ? myTrash.Value ( -anIndex ) : myImages.Value ( anIndex ); |
322 | |
323 | } // end if |
324 | |
325 | Handle( WNT_GraphicDevice ) gDev = Handle( WNT_GraphicDevice ) :: |
326 | DownCast ( PWND -> GraphicDevice () ); |
327 | |
328 | Dim ( anIndex, iw, ih ); |
329 | |
330 | iNw = ( Standard_Integer )( iw * aScaleX ); |
331 | iNh = ( Standard_Integer )( ih * aScaleY ); |
332 | |
333 | hDC = GetDC ( NULL ); |
334 | |
335 | if ( gDev -> IsPaletteDevice () ) |
336 | |
337 | hOldPal = SelectPalette ( hDC, ( HPALETTE )( gDev -> HPalette () ), FALSE ); |
338 | |
339 | hDCmemSrc = CreateCompatibleDC ( hDC ); |
340 | hDCmemDst = CreateCompatibleDC ( hDC ); |
341 | |
342 | SetStretchBltMode ( hDCmemDst, COLORONCOLOR ); |
343 | |
344 | hBitmap = CreateCompatibleBitmap ( hDC, iNw, iNh ); |
345 | |
346 | if ( hBitmap ) { |
347 | |
348 | hBmp = ( ( PWNT_Bitmap )myLastImage -> myImage ) -> hBmp; |
349 | hOldBitmap = SelectBitmap ( hDCmemSrc, hBmp ); |
350 | SelectBitmap ( hDCmemDst, hBitmap ); |
351 | |
352 | StretchBlt ( |
353 | hDCmemDst, 0, 0, iNw, iNh, |
354 | hDCmemSrc, 0, 0, iw, ih, SRCCOPY |
355 | ); |
356 | |
357 | SelectBitmap ( hDCmemSrc, hOldBitmap ); |
358 | |
359 | if ( aReplace ) { |
360 | |
361 | DeleteObject ( hBmp ); |
362 | ( ( PWNT_Bitmap )myLastImage -> myImage ) -> hBmp = hBitmap; |
363 | |
364 | } // end if |
365 | |
366 | } // end if |
367 | |
368 | DeleteDC ( hDCmemDst ); |
369 | DeleteDC ( hDCmemSrc ); |
370 | |
371 | if ( hOldPal != NULL ) SelectPalette ( hDC, hOldPal, FALSE ); |
372 | |
373 | ReleaseDC ( NULL, hDC ); |
374 | |
375 | return ( Aspect_Handle )hBitmap; |
376 | |
377 | } // end WNT_ImageManager :: Scale |
378 | //***// |
379 | //******************************** HashCode ******************************// |
380 | //***// |
381 | Standard_Integer WNT_ImageManager :: StringHashCode ( |
382 | const Standard_CString aString |
383 | ) { |
384 | |
385 | Standard_Integer i, n, aHashCode = 0; |
386 | |
387 | union { |
388 | |
389 | char charPtr[ 80 ]; |
390 | int intPtr[ 20 ]; |
391 | |
392 | } u; |
393 | |
60be1f9b |
394 | n = (Standard_Integer) strlen ( aString ); |
7fd59977 |
395 | |
396 | if ( n > 0 ) { |
397 | |
398 | if ( n < 80 ) { |
399 | |
400 | n = ( n + 3 ) / 4; |
401 | u.intPtr[ n - 1 ] = 0; |
402 | strcpy ( u.charPtr, aString ); |
403 | |
404 | } else { |
405 | |
406 | n = 20; |
407 | strncpy ( u.charPtr, aString, 80 ); |
408 | |
409 | } // end else |
410 | |
411 | for ( i = 0; i < n; ++i ) |
412 | |
413 | aHashCode = aHashCode ^ u.intPtr[ i ]; |
414 | |
415 | } // end if |
416 | |
417 | return Abs ( aHashCode ) + 1; |
418 | |
419 | } // end WNT_ImageManager :: HashCode |
420 | //***// |
421 | //**************************** ImageHandle *******************************// |
422 | //***// |
423 | Aspect_Handle WNT_ImageManager :: ImageHandle ( |
424 | const Standard_Integer anIndex |
425 | ) { |
426 | |
427 | if ( myLastIndex == anIndex ) return ( ( PWNT_Bitmap )myLastImage -> myImage ) -> hBmp; |
428 | |
429 | myLastIndex = anIndex; |
430 | myLastImage = anIndex < 0 ? myTrash.Value ( -anIndex ) : myImages.Value ( anIndex ); |
431 | |
432 | return ( ( PWNT_Bitmap )myLastImage -> myImage ) -> hBmp; |
433 | |
434 | } // end WNT_ImageManager :: ImageHandle |
435 | //***// |
436 | //******************************** Dim ***********************************// |
437 | //***// |
438 | void WNT_ImageManager :: Dim ( |
439 | const Standard_Integer anIndex, |
440 | Standard_Integer& aWidth, |
441 | Standard_Integer& aHeight |
442 | ) { |
443 | |
444 | BITMAP bmp; |
445 | |
446 | if ( myLastIndex != anIndex ) { |
447 | |
448 | myLastIndex = anIndex; |
449 | myLastImage = anIndex < 0 ? myTrash.Value ( -anIndex ) : myImages.Value ( anIndex ); |
450 | |
451 | } // end if |
452 | |
453 | GetObject ( |
454 | ( ( PWNT_Bitmap )myLastImage -> myImage ) -> hBmp, |
455 | sizeof ( BITMAP ), ( LPVOID )&bmp |
456 | ); |
457 | |
458 | aWidth = bmp.bmWidth; |
459 | aHeight = bmp.bmHeight; |
460 | |
461 | } // WNT_ImageManager :: Dim |
462 | //***// |
463 | //****************************** HashCode ********************************// |
464 | //***// |
465 | Standard_Integer WNT_ImageManager :: HashCode ( |
466 | const Standard_Integer anIndex |
467 | ) { |
468 | |
469 | if ( myLastIndex == anIndex ) return myLastImage -> myHashCode; |
470 | |
471 | myLastIndex = anIndex; |
472 | myLastImage = anIndex < 0 ? myTrash.Value ( -anIndex ) : myImages.Value ( anIndex ); |
473 | |
474 | return myLastImage -> myHashCode; |
475 | |
476 | } // end WNT_ImageManager :: HashCode |
477 | //***// |
478 | //****************************** Index ***********************************// |
479 | //***// |
480 | Standard_Integer WNT_ImageManager :: Index ( |
481 | const Standard_Integer aHashCode |
482 | ) { |
483 | |
484 | Standard_Integer retVal = 0; |
485 | |
486 | if ( myLastImage -> myHashCode == aHashCode ) return myLastIndex; |
487 | |
488 | for ( int i = 1; i <= myImages.Length (); ++i ) |
489 | |
490 | if ( myImages.Value ( i ) -> myHashCode == aHashCode ) { |
491 | |
492 | myLastImage = myImages.Value ( retVal = myLastIndex = i ); |
493 | break; |
494 | |
495 | } // end if |
496 | |
497 | if ( retVal == 0 ) |
498 | |
499 | for ( int i = 1; i <= myTrash.Length (); ++i ) |
500 | |
501 | if ( myTrash.Value ( i ) -> myHashCode == aHashCode ) { |
502 | |
503 | myLastImage = myImages.Value ( i ); |
504 | retVal = myLastIndex = -i; |
505 | break; |
506 | |
507 | } // end if |
508 | |
509 | return retVal; |
510 | |
511 | } // end WNT_ImageManager :: Index |
512 | //***// |
513 | //****************************** Delete **********************************// |
514 | //***// |
515 | void WNT_ImageManager :: Delete ( const Standard_Integer anIndex ) { |
516 | |
517 | myImages.Remove ( anIndex ); |
518 | |
519 | if ( myLastIndex == anIndex ) myLastIndex = 0; |
520 | |
521 | } // end WNT_ImageManager :: Delete |
522 | //***// |
523 | //****************************** Delete **********************************// |
524 | //***// |
525 | void WNT_ImageManager :: Discard ( const Standard_Integer anIndex ) { |
526 | |
527 | if ( anIndex > 0 ) { |
528 | |
529 | int len = myTrash.Length (); |
530 | |
531 | if ( len == TRASH_SIZE ) myTrash.Remove ( len ); |
532 | |
533 | myTrash.Prepend ( myImages.Value ( anIndex ) ); |
534 | |
535 | myImages.Remove ( anIndex ); |
536 | |
537 | if ( myLastIndex == anIndex ) myLastIndex = 0; |
538 | |
539 | } // end if |
540 | |
541 | } // end WNT_ImageManager :: Delete |
542 | //***// |
543 | //******************************** Size **********************************// |
544 | //***// |
545 | Standard_Integer WNT_ImageManager :: Size () const { |
546 | |
547 | return myImages.Length (); |
548 | |
549 | } // end WNT_ImageManager :: Size |
550 | //***// |
551 | //******************************** Add ***********************************// |
552 | //***// |
553 | void WNT_ImageManager :: Add ( const Handle_WNT_Image& anImage ) { |
554 | |
555 | myImages.Append ( myLastImage = anImage ); |
556 | |
557 | myLastIndex = myImages.Length (); |
558 | |
559 | } // end WNT_ImageManager :: Add |
560 | //***// |
561 | //******************************** Image *********************************// |
562 | //***// |
563 | Handle( WNT_Image ) WNT_ImageManager :: Image ( |
564 | const Standard_Integer anIndex |
565 | ) { |
566 | |
567 | if ( myLastIndex == anIndex ) return myLastImage; |
568 | |
569 | myLastIndex = anIndex; |
570 | myLastImage = anIndex < 0 ? myTrash.Value ( -anIndex ) : myImages.Value ( anIndex ); |
571 | |
572 | return myLastImage; |
573 | |
574 | } // end WNT_ImageManager :: Image |
575 | //***// |
576 | //******************************** Open **********************************// |
577 | //***// |
578 | Standard_Integer WNT_ImageManager :: Open ( |
579 | const Aspect_Handle aDC, |
580 | const Standard_Integer aWidth, |
581 | const Standard_Integer aHeight, |
582 | const Standard_Integer aHashCode |
583 | ) { |
584 | |
585 | HDC hdc = ( HDC )aDC; |
586 | HBITMAP hBmp = CreateCompatibleBitmap ( hdc, aWidth, aHeight ); |
587 | |
588 | myImages.Append ( myLastImage = new WNT_Image ( hBmp, aHashCode ) ); |
589 | |
590 | return myLastIndex = myImages.Length (); |
591 | |
592 | } // end WNT_ImageMagager :: Open |
593 | //***// |
594 | //************************************************************************// |