00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "plDevs.h"
00025
00026 #ifdef PLD_wingcc
00027
00028 #include <string.h>
00029 #include <windows.h>
00030 #ifdef _WIN64
00031 #define GWL_USERDATA GWLP_USERDATA
00032 #define GCL_HCURSOR GCLP_HCURSOR
00033 #endif
00034
00035 #include "plplotP.h"
00036 #include "drivers.h"
00037 #include "plevent.h"
00038
00039 #ifdef HAVE_FREETYPE
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include "plfreetype.h"
00059
00060 #ifndef max_number_of_grey_levels_used_in_text_smoothing
00061 #define max_number_of_grey_levels_used_in_text_smoothing 64
00062 #endif
00063
00064 #endif
00065
00066
00067
00068
00069 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_wingcc = "wingcc:Win32 (GCC):1:wingcc:9:wingcc\n";
00070
00071
00072
00073 typedef struct
00074 {
00075 PLFLT scale;
00076 PLINT width;
00077 PLINT height;
00078
00079 PLFLT PRNT_scale;
00080 PLINT PRNT_width;
00081 PLINT PRNT_height;
00082
00083 char FT_smooth_text;
00084
00085
00086
00087
00088 COLORREF colour;
00089 COLORREF oldcolour;
00090 MSG msg;
00091 WNDCLASSEX wndclass;
00092 HWND hwnd;
00093 HPEN pen;
00094 HDC hdc;
00095 HDC hdc2;
00096 HDC SCRN_hdc;
00097 HDC PRNT_hdc;
00098 PAINTSTRUCT ps;
00099 RECT rect;
00100 RECT oldrect;
00101 RECT paintrect;
00102 HBRUSH fillbrush;
00103 HCURSOR cursor;
00104 HBITMAP bitmap;
00105 HGDIOBJ oldobject;
00106 HMENU PopupMenu;
00107
00108 PLINT draw_mode;
00109 char truecolour;
00110 char waiting;
00111
00112 char enterresize;
00113 char already_erased;
00114
00115 struct wingcc_Dev *push;
00116
00117 } wingcc_Dev;
00118
00119
00120 void plD_dispatch_init_wingcc( PLDispatchTable *pdt );
00121
00122 void plD_init_wingcc( PLStream * );
00123 void plD_line_wingcc( PLStream *, short, short, short, short );
00124 void plD_polyline_wingcc( PLStream *, short *, short *, PLINT );
00125 void plD_eop_wingcc( PLStream * );
00126 void plD_bop_wingcc( PLStream * );
00127 void plD_tidy_wingcc( PLStream * );
00128 void plD_state_wingcc( PLStream *, PLINT );
00129 void plD_esc_wingcc( PLStream *, PLINT, void * );
00130
00131 #ifdef HAVE_FREETYPE
00132
00133 static void plD_pixel_wingcc( PLStream *pls, short x, short y );
00134 static void plD_pixelV_wingcc( PLStream *pls, short x, short y );
00135 static PLINT plD_read_pixel_wingcc( PLStream *pls, short x, short y );
00136 static void plD_set_pixel_wingcc( PLStream *pls, short x, short y, PLINT colour );
00137 static void plD_set_pixelV_wingcc( PLStream *pls, short x, short y, PLINT colour );
00138 static void init_freetype_lv1( PLStream *pls );
00139 static void init_freetype_lv2( PLStream *pls );
00140
00141 #endif
00142
00143
00144
00145
00146
00147
00148 static int GetRegValue( char *key_name, char *key_word, char *buffer, int size );
00149 static int SetRegValue( char *key_name, char *key_word, char *buffer, int dwType, int size );
00150 static void Resize( PLStream *pls );
00151 static void plD_fill_polygon_wingcc( PLStream *pls );
00152 static void CopySCRtoBMP( PLStream *pls );
00153 static void PrintPage( PLStream *pls );
00154 static void UpdatePageMetrics( PLStream *pls, char flag );
00155
00156 #define SetRegStringValue( a, b, c ) SetRegValue( a, b, c, REG_SZ, strlen( c ) + 1 )
00157 #define SetRegBinaryValue( a, b, c, d ) SetRegValue( a, b, (char *) c, REG_BINARY, d )
00158 #define SetRegIntValue( a, b, c ) SetRegValue( a, b, (char *) c, REG_DWORD, 4 )
00159 #define GetRegStringValue( a, b, c, d ) GetRegValue( a, b, c, d )
00160 #define GetRegIntValue( a, b, c ) GetRegValue( a, b, (char *) c, 4 )
00161 #define GetRegBinaryValue( a, b, c, d ) GetRegValue( a, b, (char *) c, d )
00162
00163
00164
00165
00166
00167 #if defined ( _MSC_VER )
00168 #define Debug( a ) do { if ( pls->debug ) { fprintf( stderr, ( a ) ); } } while ( 0 )
00169 #define Debug2( a, b ) do { if ( pls->debug ) { fprintf( stderr, ( a ), ( b ) ); } } while ( 0 )
00170 #define Debug3( a, b, c ) do { if ( pls->debug ) { fprintf( stderr, ( a ), ( b ), ( c ) ); } } while ( 0 )
00171 #elif defined ( __BORLANDC__ )
00172 #define Debug if ( pls->debug ) printf
00173 #define Debug2 if ( pls->debug ) printf
00174 #define Debug3 if ( pls->debug ) printf
00175 #else
00176 #define Verbose( ... ) do { if ( pls->verbose ) { fprintf( stderr, __VA_ARGS__ ); } } while ( 0 )
00177 #define Debug( ... ) do { if ( pls->debug ) { fprintf( stderr, __VA_ARGS__ ); } } while ( 0 )
00178 #define Debug2( ... ) do { if ( pls->debug ) { fprintf( stderr, __VA_ARGS__ ); } } while ( 0 )
00179 #define Debug3( ... ) do { if ( pls->debug ) { fprintf( stderr, __VA_ARGS__ ); } } while ( 0 )
00180 #endif
00181
00182 #define ReportWinError() do { \
00183 LPVOID lpMsgBuf; \
00184 FormatMessage( \
00185 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, \
00186 NULL, GetLastError(), \
00187 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR) &lpMsgBuf, 0, NULL ); \
00188 MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK | MB_ICONINFORMATION ); \
00189 LocalFree( lpMsgBuf ); } while ( 0 )
00190
00191 #define CrossHairCursor() do { \
00192 dev->cursor = LoadCursor( NULL, IDC_CROSS ); \
00193 SetClassLong( dev->hwnd, GCL_HCURSOR, (long) dev->cursor ); \
00194 SetCursor( dev->cursor ); } while ( 0 )
00195
00196 #define NormalCursor() do { \
00197 dev->cursor = LoadCursor( NULL, IDC_ARROW ); \
00198 SetClassLong( dev->hwnd, GCL_HCURSOR, (long) dev->cursor ); \
00199 SetCursor( dev->cursor ); } while ( 0 )
00200
00201 #define BusyCursor() do { \
00202 dev->cursor = LoadCursor( NULL, IDC_WAIT ); \
00203 SetClassLong( dev->hwnd, GCL_HCURSOR, (long) dev->cursor ); \
00204 SetCursor( dev->cursor ); } while ( 0 )
00205
00206 #define PopupPrint 0x08A1
00207 #define PopupNextPage 0x08A2
00208 #define PopupQuit 0x08A3
00209
00210
00211 void plD_dispatch_init_wingcc( PLDispatchTable *pdt )
00212 {
00213 #ifndef ENABLE_DYNDRIVERS
00214 pdt->pl_MenuStr = "Win32 GCC device";
00215 pdt->pl_DevName = "wingcc";
00216 #endif
00217 pdt->pl_type = plDevType_Interactive;
00218 pdt->pl_seq = 9;
00219 pdt->pl_init = (plD_init_fp) plD_init_wingcc;
00220 pdt->pl_line = (plD_line_fp) plD_line_wingcc;
00221 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_wingcc;
00222 pdt->pl_eop = (plD_eop_fp) plD_eop_wingcc;
00223 pdt->pl_bop = (plD_bop_fp) plD_bop_wingcc;
00224 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_wingcc;
00225 pdt->pl_state = (plD_state_fp) plD_state_wingcc;
00226 pdt->pl_esc = (plD_esc_fp) plD_esc_wingcc;
00227 }
00228
00229 static char* szWndClass = "PlplotWin";
00230
00231
00232
00233
00234
00235
00236
00237
00238 LRESULT CALLBACK PlplotWndProc( HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
00239 {
00240 PLStream *pls = NULL;
00241 wingcc_Dev *dev = NULL;
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 if ( nMsg == WM_CREATE )
00254 {
00255 return ( 0 );
00256 }
00257 else
00258 {
00259 #ifndef _WIN64
00260 #define GetWindowLongPtr GetWindowLong
00261 #endif
00262 pls = (PLStream *) GetWindowLongPtr( hwnd, GWL_USERDATA );
00263 if ( pls )
00264 {
00265 dev = (wingcc_Dev *) pls->dev;
00266 }
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 switch ( nMsg )
00280 {
00281 case WM_DESTROY:
00282 if ( dev )
00283 Debug( "WM_DESTROY\t" );
00284 PostQuitMessage( 0 );
00285 return ( 0 );
00286 break;
00287
00288 case WM_PAINT:
00289 if ( dev )
00290 {
00291 Debug( "WM_PAINT\t" );
00292 if ( GetUpdateRect( dev->hwnd, &dev->paintrect, TRUE ) )
00293 {
00294 BusyCursor();
00295 BeginPaint( dev->hwnd, &dev->ps );
00296
00297 if ( ( dev->waiting == 1 ) && ( dev->already_erased == 1 ) )
00298 {
00299 Debug( "Remaking\t" );
00300
00301 if ( dev->ps.fErase )
00302 {
00303 dev->oldcolour = SetBkColor( dev->hdc, RGB( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b ) );
00304 ExtTextOut( dev->hdc, 0, 0, ETO_OPAQUE, &dev->rect, "", 0, 0 );
00305 SetBkColor( dev->hdc, dev->oldcolour );
00306 }
00307
00308 plRemakePlot( pls );
00309 CopySCRtoBMP( pls );
00310 dev->already_erased++;
00311 }
00312 else if ( ( dev->waiting == 1 ) && ( dev->already_erased == 2 ) )
00313 {
00314 dev->oldobject = SelectObject( dev->hdc2, dev->bitmap );
00315 BitBlt( dev->hdc, dev->paintrect.left, dev->paintrect.top,
00316 dev->paintrect.right, dev->paintrect.bottom,
00317 dev->hdc2, dev->paintrect.left, dev->paintrect.top, SRCCOPY );
00318 SelectObject( dev->hdc2, dev->oldobject );
00319 }
00320
00321 EndPaint( dev->hwnd, &dev->ps );
00322 NormalCursor();
00323 return ( 0 );
00324 }
00325 }
00326 return ( 1 );
00327 break;
00328
00329 case WM_SIZE:
00330 if ( dev )
00331 {
00332 Debug( "WM_SIZE\t" );
00333
00334 if ( dev->enterresize == 0 )
00335 Resize( pls );
00336 }
00337 return ( 0 );
00338 break;
00339
00340 case WM_ENTERSIZEMOVE:
00341 if ( dev )
00342 {
00343 Debug( "WM_ENTERSIZEMOVE\t" );
00344 dev->enterresize = 1;
00345 }
00346 return ( 0 );
00347 break;
00348
00349
00350 case WM_EXITSIZEMOVE:
00351 if ( dev )
00352 {
00353 Debug( "WM_EXITSIZEMOVE\t" );
00354 Resize( pls );
00355 dev->enterresize = 0;
00356 }
00357 return ( 0 );
00358 break;
00359
00360 case WM_ERASEBKGND:
00361
00362 if ( dev )
00363 {
00364 if ( dev->already_erased == 0 )
00365 {
00366 Debug( "WM_ERASEBKGND\t" );
00367
00368
00369
00370
00371
00372
00373
00374 dev->oldcolour = SetBkColor( dev->hdc, RGB( pls->cmap0[0].r, pls->cmap0[0].g, pls->cmap0[0].b ) );
00375 ExtTextOut( dev->hdc, 0, 0, ETO_OPAQUE, &dev->rect, "", 0, 0 );
00376 SetBkColor( dev->hdc, dev->oldcolour );
00377
00378 dev->already_erased = 1;
00379 return ( 1 );
00380 }
00381 }
00382 return ( 0 );
00383 break;
00384
00385 case WM_COMMAND:
00386 if ( dev )
00387 Debug( "WM_COMMAND\t" );
00388 return ( 0 );
00389 break;
00390 }
00391
00392
00393
00394 return DefWindowProc( hwnd, nMsg, wParam, lParam );
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404 void
00405 plD_init_wingcc( PLStream *pls )
00406 {
00407 wingcc_Dev *dev;
00408
00409 #ifdef HAVE_FREETYPE
00410 static int freetype = 0;
00411 static int smooth_text = 0;
00412 static int save_reg = 0;
00413 FT_Data *FT;
00414
00415
00416
00417
00418
00419 char key_name[] = "Software\\PLplot\\wingcc";
00420 char Keyword_text[] = "freetype";
00421 char Keyword_smooth[] = "smooth";
00422 #endif
00423
00424 DrvOpt wingcc_options[] = {
00425 #ifdef HAVE_FREETYPE
00426 { "text", DRV_INT, &freetype, "Use driver text (FreeType)" },
00427 { "smooth", DRV_INT, &smooth_text, "Turn text smoothing on (1) or off (0)" },
00428 { "save", DRV_INT, &save_reg, "Save defaults to registary" },
00429
00430 #endif
00431 { NULL, DRV_INT, NULL, NULL }
00432 };
00433
00434
00435
00436 if ( pls->dev != NULL )
00437 free( (void *) pls->dev );
00438
00439 pls->dev = calloc( 1, (size_t) sizeof ( wingcc_Dev ) );
00440 if ( pls->dev == NULL )
00441 plexit( "plD_init_wingcc_Dev: Out of memory." );
00442
00443 dev = (wingcc_Dev *) pls->dev;
00444
00445 pls->icol0 = 1;
00446
00447 pls->termin = 1;
00448 pls->graphx = GRAPHICS_MODE;
00449 pls->dev_fill0 = 1;
00450 pls->dev_xor = 1;
00451 pls->dev_clear = 0;
00452 pls->dev_dash = 0;
00453 pls->plbuf_write = 1;
00454
00455 if ( !pls->colorset )
00456 pls->color = 1;
00457
00458
00459 #ifdef HAVE_FREETYPE
00460
00461
00462
00463
00464
00465
00466
00467
00468 GetRegIntValue( key_name, Keyword_text, &freetype );
00469 GetRegIntValue( key_name, Keyword_smooth, &smooth_text );
00470
00471 #endif
00472
00473
00474
00475 plParseDrvOpts( wingcc_options );
00476
00477 #ifdef HAVE_FREETYPE
00478
00479
00480
00481
00482
00483 if ( save_reg == 1 )
00484 {
00485 SetRegIntValue( key_name, Keyword_text, &freetype );
00486 SetRegIntValue( key_name, Keyword_smooth, &smooth_text );
00487 }
00488
00489 #endif
00490
00491
00492
00493 if ( pls->xlength <= 0 || pls->ylength <= 0 )
00494 {
00495
00496
00497 plspage( 0., 0., 800, 600, 0, 0 );
00498 }
00499
00500 dev->width = pls->xlength - 1;
00501 dev->height = pls->ylength - 1;
00502
00503
00504
00505
00506
00507
00508 memset( &dev->wndclass, 0, sizeof ( WNDCLASSEX ) );
00509
00510
00511 dev->wndclass.lpszClassName = szWndClass;
00512
00513
00514 dev->wndclass.cbSize = sizeof ( WNDCLASSEX );
00515
00516
00517 dev->wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC | CS_PARENTDC;
00518
00519
00520 dev->wndclass.lpfnWndProc = PlplotWndProc;
00521
00522
00523
00524 dev->wndclass.hInstance = GetModuleHandle( NULL );
00525
00526
00527 dev->wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
00528 dev->wndclass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
00529 dev->wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
00530
00531 dev->wndclass.hbrBackground = NULL;
00532
00533 dev->wndclass.cbWndExtra = sizeof ( pls );
00534
00535
00536
00537
00538
00539
00540 RegisterClassEx( &dev->wndclass );
00541
00542
00543
00544
00545
00546 dev->hwnd = CreateWindowEx( WS_EX_WINDOWEDGE + WS_EX_LEFT,
00547 szWndClass,
00548 pls->program,
00549 WS_OVERLAPPEDWINDOW,
00550 pls->xoffset,
00551 pls->yoffset,
00552 pls->xlength,
00553 pls->ylength,
00554 NULL,
00555 NULL,
00556 dev->wndclass.hInstance,
00557 NULL
00558 );
00559
00560
00561
00562
00563
00564
00565
00566
00567 #ifdef _WIN64
00568 SetWindowLongPtr( dev->hwnd, GWL_USERDATA, (LONG_PTR) pls );
00569 #else
00570 SetWindowLong( dev->hwnd, GWL_USERDATA, (LONG) pls );
00571 #endif
00572
00573 dev->SCRN_hdc = dev->hdc = GetDC( dev->hwnd );
00574
00575
00576
00577
00578
00579 dev->PopupMenu = CreatePopupMenu();
00580 AppendMenu( dev->PopupMenu, MF_STRING, PopupPrint, "Print" );
00581 AppendMenu( dev->PopupMenu, MF_STRING, PopupNextPage, "Next Page" );
00582 AppendMenu( dev->PopupMenu, MF_STRING, PopupQuit, "Quit" );
00583
00584 #ifdef HAVE_FREETYPE
00585
00586 if ( freetype )
00587 {
00588 pls->dev_text = 1;
00589 pls->dev_unicode = 1;
00590 init_freetype_lv1( pls );
00591 FT = (FT_Data *) pls->FT;
00592 FT->want_smooth_text = smooth_text;
00593 }
00594
00595 #endif
00596
00597
00598
00599 plD_state_wingcc( pls, PLSTATE_COLOR0 );
00600
00601
00602
00603
00604
00605 ShowWindow( dev->hwnd, SW_SHOWDEFAULT );
00606 SetForegroundWindow( dev->hwnd );
00607
00608
00609
00610
00611
00612
00613 if ( pls->xdpi <= 0 )
00614 {
00615 plspage( GetDeviceCaps( dev->hdc, HORZRES ) / GetDeviceCaps( dev->hdc, HORZSIZE ) * 25.4,
00616 GetDeviceCaps( dev->hdc, VERTRES ) / GetDeviceCaps( dev->hdc, VERTSIZE ) * 25.4, 0, 0, 0, 0 );
00617 }
00618 else
00619 {
00620 pls->ydpi = pls->xdpi;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 GetClientRect( dev->hwnd, &dev->rect );
00632 dev->width = dev->rect.right;
00633 dev->height = dev->rect.bottom;
00634
00635 if ( dev->width > dev->height )
00636 {
00637 dev->scale = (PLFLT) ( PIXELS_X - 1 ) / dev->width;
00638 }
00639 else
00640 {
00641 dev->scale = (PLFLT) PIXELS_Y / dev->height;
00642 }
00643
00644 Debug2( "Scale = %f (FLT)\n", dev->scale );
00645
00646 plP_setpxl( dev->scale * pls->xdpi / 25.4, dev->scale * pls->ydpi / 25.4 );
00647 plP_setphy( 0, (PLINT) ( dev->scale * dev->width ), 0, (PLINT) ( dev->scale * dev->height ) );
00648
00649
00650 if ( pls->dev_eofill )
00651 SetPolyFillMode( dev->hdc, ALTERNATE );
00652 else
00653 SetPolyFillMode( dev->hdc, WINDING );
00654
00655 #ifdef HAVE_FREETYPE
00656 if ( pls->dev_text )
00657 {
00658 init_freetype_lv2( pls );
00659 }
00660 #endif
00661 }
00662
00663
00664
00665
00666
00667
00668
00669 void
00670 plD_line_wingcc( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
00671 {
00672 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00673 POINT points[2];
00674
00675
00676 points[0].x = (LONG) ( x1a / dev->scale );
00677 points[1].x = (LONG) ( x2a / dev->scale );
00678 points[0].y = (LONG) ( dev->height - ( y1a / dev->scale ) );
00679 points[1].y = (LONG) ( dev->height - ( y2a / dev->scale ) );
00680
00681 dev->oldobject = SelectObject( dev->hdc, dev->pen );
00682
00683 if ( points[0].x != points[1].x || points[0].y != points[1].y )
00684 {
00685 Polyline( dev->hdc, points, 2 );
00686 }
00687 else
00688 {
00689 SetPixel( dev->hdc, points[0].x, points[0].y, dev->colour );
00690 }
00691 SelectObject( dev->hdc, dev->oldobject );
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701 void
00702 plD_polyline_wingcc( PLStream *pls, short *xa, short *ya, PLINT npts )
00703 {
00704 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00705 int i;
00706 POINT *points = NULL;
00707
00708 if ( npts > 0 )
00709 {
00710 points = GlobalAlloc( GMEM_ZEROINIT | GMEM_FIXED, (size_t) npts * sizeof ( POINT ) );
00711 if ( points != NULL )
00712 {
00713 for ( i = 0; i < npts; i++ )
00714 {
00715 points[i].x = (LONG) ( xa[i] / dev->scale );
00716 points[i].y = (LONG) ( dev->height - ( ya[i] / dev->scale ) );
00717 }
00718 dev->oldobject = SelectObject( dev->hdc, dev->pen );
00719 Polyline( dev->hdc, points, npts );
00720 SelectObject( dev->hdc, dev->oldobject );
00721 GlobalFree( points );
00722 }
00723 else
00724 {
00725 plexit( "Could not allocate memory to \"plD_polyline_wingcc\"\n" );
00726 }
00727 }
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 static void
00737 plD_fill_polygon_wingcc( PLStream *pls )
00738 {
00739 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00740 int i;
00741 POINT *points = NULL;
00742 HPEN hpen, hpenOld;
00743
00744 if ( pls->dev_npts > 0 )
00745 {
00746 points = GlobalAlloc( GMEM_ZEROINIT, (size_t) pls->dev_npts * sizeof ( POINT ) );
00747
00748 if ( points == NULL )
00749 plexit( "Could not allocate memory to \"plD_fill_polygon_wingcc\"\n" );
00750
00751 for ( i = 0; i < pls->dev_npts; i++ )
00752 {
00753 points[i].x = (PLINT) ( pls->dev_x[i] / dev->scale );
00754 points[i].y = (PLINT) ( dev->height - ( pls->dev_y[i] / dev->scale ) );
00755 }
00756
00757 dev->fillbrush = CreateSolidBrush( dev->colour );
00758 hpen = CreatePen( PS_SOLID, 1, dev->colour );
00759 dev->oldobject = SelectObject( dev->hdc, dev->fillbrush );
00760 hpenOld = SelectObject( dev->hdc, hpen );
00761 Polygon( dev->hdc, points, pls->dev_npts );
00762 SelectObject( dev->hdc, dev->oldobject );
00763 DeleteObject( dev->fillbrush );
00764 SelectObject( dev->hdc, hpenOld );
00765 DeleteObject( hpen );
00766 GlobalFree( points );
00767 }
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777 static void CopySCRtoBMP( PLStream *pls )
00778 {
00779 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00780
00781
00782
00783
00784
00785 if ( dev->hdc2 != NULL )
00786 DeleteDC( dev->hdc2 );
00787 if ( dev->bitmap != NULL )
00788 DeleteObject( dev->bitmap );
00789
00790 dev->hdc2 = CreateCompatibleDC( dev->hdc );
00791 GetClientRect( dev->hwnd, &dev->rect );
00792 dev->bitmap = CreateCompatibleBitmap( dev->hdc, dev->rect.right, dev->rect.bottom );
00793 dev->oldobject = SelectObject( dev->hdc2, dev->bitmap );
00794 BitBlt( dev->hdc2, 0, 0, dev->rect.right, dev->rect.bottom, dev->hdc, 0, 0, SRCCOPY );
00795 SelectObject( dev->hdc2, dev->oldobject );
00796 }
00797
00798
00799
00800 void
00801 plD_eop_wingcc( PLStream *pls )
00802 {
00803 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00804
00805 Debug( "End of the page\n" );
00806 CopySCRtoBMP( pls );
00807 dev->already_erased = 2;
00808
00809 NormalCursor();
00810
00811 if ( !pls->nopause )
00812 {
00813 dev->waiting = 1;
00814 while ( GetMessage( &dev->msg, NULL, 0, 0 ) )
00815 {
00816 TranslateMessage( &dev->msg );
00817 switch ( (int) dev->msg.message )
00818 {
00819 case WM_CONTEXTMENU:
00820 case WM_RBUTTONDOWN:
00821 TrackPopupMenu( dev->PopupMenu, TPM_CENTERALIGN | TPM_RIGHTBUTTON, LOWORD( dev->msg.lParam ),
00822 HIWORD( dev->msg.lParam ), 0, dev->hwnd, NULL );
00823 break;
00824
00825 case WM_CHAR:
00826 if ( ( (TCHAR) ( dev->msg.wParam ) == 32 ) ||
00827 ( (TCHAR) ( dev->msg.wParam ) == 13 ) )
00828 {
00829 dev->waiting = 0;
00830 }
00831 else if ( ( (TCHAR) ( dev->msg.wParam ) == 27 ) ||
00832 ( (TCHAR) ( dev->msg.wParam ) == 'q' ) ||
00833 ( (TCHAR) ( dev->msg.wParam ) == 'Q' ) )
00834 {
00835 dev->waiting = 0;
00836 PostQuitMessage( 0 );
00837 }
00838 break;
00839
00840 case WM_LBUTTONDBLCLK:
00841 Debug( "WM_LBUTTONDBLCLK\t" );
00842 dev->waiting = 0;
00843 break;
00844
00845 case WM_COMMAND:
00846 switch ( LOWORD( dev->msg.wParam ) )
00847 {
00848 case PopupPrint:
00849 Debug( "PopupPrint" );
00850 PrintPage( pls );
00851 break;
00852 case PopupNextPage:
00853 Debug( "PopupNextPage" );
00854 dev->waiting = 0;
00855 break;
00856 case PopupQuit:
00857 Debug( "PopupQuit" );
00858 dev->waiting = 0;
00859 PostQuitMessage( 0 );
00860 break;
00861 }
00862 break;
00863
00864 default:
00865 DispatchMessage( &dev->msg );
00866 break;
00867 }
00868 if ( dev->waiting == 0 )
00869 break;
00870 }
00871 }
00872 }
00873
00874
00875
00876
00877 void
00878 plD_bop_wingcc( PLStream *pls )
00879 {
00880 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00881 #ifdef HAVE_FREETYPE
00882 FT_Data *FT = (FT_Data *) pls->FT;
00883 #endif
00884 Debug( "Start of Page\t" );
00885
00886
00887
00888
00889
00890
00891 BusyCursor();
00892 dev->already_erased = 0;
00893 RedrawWindow( dev->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW );
00894
00895 plD_state_wingcc( pls, PLSTATE_COLOR0 );
00896 }
00897
00898 void
00899 plD_tidy_wingcc( PLStream *pls )
00900 {
00901 wingcc_Dev *dev = NULL;
00902
00903 #ifdef HAVE_FREETYPE
00904 if ( pls->dev_text )
00905 {
00906 FT_Data *FT = (FT_Data *) pls->FT;
00907 plscmap0n( FT->ncol0_org );
00908 plD_FreeType_Destroy( pls );
00909 }
00910 #endif
00911 Debug( "plD_tidy_wingcc" );
00912
00913 if ( pls->dev != NULL )
00914 {
00915 dev = (wingcc_Dev *) pls->dev;
00916
00917 DeleteMenu( dev->PopupMenu, PopupPrint, 0 );
00918 DeleteMenu( dev->PopupMenu, PopupNextPage, 0 );
00919 DeleteMenu( dev->PopupMenu, PopupQuit, 0 );
00920 DestroyMenu( dev->PopupMenu );
00921
00922 if ( dev->hdc2 != NULL )
00923 DeleteDC( dev->hdc2 );
00924 if ( dev->hdc != NULL )
00925 ReleaseDC( dev->hwnd, dev->hdc );
00926 if ( dev->bitmap != NULL )
00927 DeleteObject( dev->bitmap );
00928
00929 free_mem( pls->dev );
00930 }
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 void
00943 plD_state_wingcc( PLStream *pls, PLINT op )
00944 {
00945 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00946
00947 switch ( op )
00948 {
00949 case PLSTATE_COLOR0:
00950 case PLSTATE_COLOR1:
00951 dev->colour = RGB( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b );
00952 break;
00953
00954 case PLSTATE_CMAP0:
00955 case PLSTATE_CMAP1:
00956 dev->colour = RGB( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b );
00957
00958
00959 break;
00960 }
00961
00962 if ( dev->pen != NULL )
00963 DeleteObject( dev->pen );
00964 dev->pen = CreatePen( PS_SOLID, pls->width, dev->colour );
00965 }
00966
00967 void
00968 plD_esc_wingcc( PLStream *pls, PLINT op, void *ptr )
00969 {
00970 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
00971
00972 switch ( op )
00973 {
00974 case PLESC_GETC:
00975 break;
00976
00977 case PLESC_FILL:
00978 plD_fill_polygon_wingcc( pls );
00979 break;
00980
00981 case PLESC_DOUBLEBUFFERING:
00982 break;
00983
00984 case PLESC_XORMOD:
00985 if ( *(PLINT *) ( ptr ) == 0 )
00986 SetROP2( dev->hdc, R2_COPYPEN );
00987 else
00988 SetROP2( dev->hdc, R2_XORPEN );
00989 break;
00990
00991 #ifdef HAVE_FREETYPE
00992 case PLESC_HAS_TEXT:
00993 plD_render_freetype_text( pls, (EscText *) ptr );
00994 break;
00995
00996
00997
00998
00999
01000 #endif
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 static void Resize( PLStream *pls )
01018 {
01019 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01020 #ifdef HAVE_FREETYPE
01021 FT_Data *FT = (FT_Data *) pls->FT;
01022 #endif
01023 Debug( "Resizing" );
01024
01025 if ( dev->waiting == 1 )
01026 {
01027 memcpy( &dev->oldrect, &dev->rect, sizeof ( RECT ) );
01028 GetClientRect( dev->hwnd, &dev->rect );
01029 Debug3( "[%d %d]", dev->rect.right, dev->rect.bottom );
01030
01031 if ( ( dev->rect.right > 0 ) && ( dev->rect.bottom > 0 ) )
01032 {
01033 if ( memcmp( &dev->rect, &dev->oldrect, sizeof ( RECT ) ) != 0 )
01034 {
01035 dev->already_erased = 0;
01036 dev->width = dev->rect.right;
01037 dev->height = dev->rect.bottom;
01038 if ( dev->width > dev->height )
01039 {
01040 dev->scale = (PLFLT) ( PIXELS_X - 1 ) / dev->width;
01041 }
01042 else
01043 {
01044 dev->scale = (PLFLT) PIXELS_Y / dev->height;
01045 }
01046
01047 #ifdef HAVE_FREETYPE
01048 if ( FT )
01049 {
01050 FT->scale = dev->scale;
01051 FT->ymax = dev->height;
01052 }
01053 #endif
01054 }
01055 RedrawWindow( dev->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW );
01056 }
01057 else
01058 {
01059 memcpy( &dev->rect, &dev->oldrect, sizeof ( RECT ) );
01060 }
01061 }
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 static int SetRegValue( char *key_name, char *key_word, char *buffer, int dwType, int size )
01074 {
01075 int j = 0;
01076
01077 DWORD lpdwDisposition;
01078 HKEY hKey;
01079
01080 j = RegCreateKeyEx(
01081 HKEY_CURRENT_USER,
01082 key_name,
01083 0,
01084 NULL,
01085 REG_OPTION_NON_VOLATILE,
01086 KEY_WRITE,
01087 NULL,
01088 &hKey,
01089 &lpdwDisposition
01090 );
01091
01092 if ( j == ERROR_SUCCESS )
01093 {
01094 RegSetValueEx( hKey, key_word, 0, dwType, buffer, size );
01095 RegCloseKey( hKey );
01096 }
01097 return ( j );
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 static int GetRegValue( char *key_name, char *key_word, char *buffer, int size )
01110 {
01111 int ret = 0;
01112 HKEY hKey;
01113 int dwType;
01114 int dwSize = size;
01115
01116 if ( RegOpenKeyEx( HKEY_CURRENT_USER, key_name, 0, KEY_READ, &hKey ) == ERROR_SUCCESS )
01117 {
01118 if ( RegQueryValueEx( hKey, key_word, 0, (LPDWORD) &dwType, buffer, (LPDWORD) &dwSize ) == ERROR_SUCCESS )
01119 {
01120 ret = 1;
01121 }
01122 RegCloseKey( hKey );
01123 }
01124 return ( ret );
01125 }
01126
01127 #ifdef HAVE_FREETYPE
01128
01129
01130
01131
01132
01133
01134
01135
01136 static void plD_pixel_wingcc( PLStream *pls, short x, short y )
01137 {
01138 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01139
01140 SetPixel( dev->hdc, x, y, dev->colour );
01141 }
01142
01143 static void plD_pixelV_wingcc( PLStream *pls, short x, short y )
01144 {
01145 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01146
01147 SetPixelV( dev->hdc, x, y, dev->colour );
01148 }
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 static void plD_set_pixel_wingcc( PLStream *pls, short x, short y, PLINT colour )
01159 {
01160 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01161
01162 SetPixel( dev->hdc, x, y, colour );
01163 }
01164
01165 static void plD_set_pixelV_wingcc( PLStream *pls, short x, short y, PLINT colour )
01166 {
01167 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01168
01169 SetPixelV( dev->hdc, x, y, colour );
01170 }
01171
01172
01173
01174
01175
01176
01177
01178
01179 static PLINT plD_read_pixel_wingcc( PLStream *pls, short x, short y )
01180 {
01181 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01182
01183 return ( GetPixel( dev->hdc, x, y ) );
01184 }
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 static void init_freetype_lv1( PLStream *pls )
01197 {
01198 FT_Data *FT;
01199 int x;
01200 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01201
01202 plD_FreeType_init( pls );
01203
01204 FT = (FT_Data *) pls->FT;
01205
01206
01207
01208
01209
01210
01211
01212
01213 x = GetDeviceCaps( dev->hdc, RASTERCAPS );
01214
01215 if ( x & RC_BITBLT )
01216 FT->pixel = (plD_pixel_fp) plD_pixelV_wingcc;
01217 else
01218 FT->pixel = (plD_pixel_fp) plD_pixel_wingcc;
01219
01220
01221
01222
01223
01224
01225 if ( GetDeviceCaps( dev->hdc, BITSPIXEL ) > 24 )
01226 {
01227 FT->BLENDED_ANTIALIASING = 1;
01228 FT->read_pixel = (plD_read_pixel_fp) plD_read_pixel_wingcc;
01229
01230 if ( x & RC_BITBLT )
01231 FT->set_pixel = (plD_set_pixel_fp) plD_set_pixelV_wingcc;
01232 else
01233 FT->set_pixel = (plD_set_pixel_fp) plD_set_pixel_wingcc;
01234 }
01235 }
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262 static void init_freetype_lv2( PLStream *pls )
01263 {
01264 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01265 FT_Data *FT = (FT_Data *) pls->FT;
01266
01267 FT->scale = dev->scale;
01268 FT->ymax = dev->height;
01269 FT->invert_y = 1;
01270
01271 if ( ( FT->want_smooth_text == 1 ) && ( FT->BLENDED_ANTIALIASING == 0 ) )
01272 {
01273 FT->ncol0_org = pls->ncol0;
01274 FT->ncol0_xtra = 16777216 - ( pls->ncol1 + pls->ncol0 );
01275 FT->ncol0_width = max_number_of_grey_levels_used_in_text_smoothing;
01276 FT->ncol0_width = max_number_of_grey_levels_used_in_text_smoothing;
01277 plscmap0n( FT->ncol0_org + ( FT->ncol0_width * pls->ncol0 ) );
01278
01279
01280
01281
01282
01283 {
01284 PLINT level_save;
01285 level_save = pls->level;
01286 pls->level = 0;
01287 pl_set_extended_cmap0( pls, FT->ncol0_width, FT->ncol0_org );
01288 pls->level = level_save;
01289 }
01290 FT->smooth_text = 1;
01291 }
01292 else if ( ( FT->want_smooth_text == 1 ) && ( FT->BLENDED_ANTIALIASING == 1 ) )
01293 {
01294 FT->smooth_text = 1;
01295 }
01296 }
01297 #endif
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 static void UpdatePageMetrics( PLStream *pls, char flag )
01309 {
01310 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01311 #ifdef HAVE_FREETYPE
01312 FT_Data *FT = (FT_Data *) pls->FT;
01313 #endif
01314
01315 if ( flag == 1 )
01316 {
01317 dev->width = GetDeviceCaps( dev->hdc, HORZRES );
01318 dev->height = GetDeviceCaps( dev->hdc, VERTRES );
01319 }
01320 else
01321 {
01322 GetClientRect( dev->hwnd, &dev->rect );
01323 dev->width = dev->rect.right;
01324 dev->height = dev->rect.bottom;
01325 }
01326
01327 if ( dev->width > dev->height )
01328 {
01329 dev->scale = (PLFLT) ( PIXELS_X - 1 ) / dev->width;
01330 }
01331 else
01332 {
01333 dev->scale = (PLFLT) PIXELS_Y / dev->height;
01334 }
01335
01336 #ifdef HAVE_FREETYPE
01337 if ( FT )
01338 {
01339 FT->scale = dev->scale;
01340 FT->ymax = dev->height;
01341 if ( GetDeviceCaps( dev->hdc, RASTERCAPS ) & RC_BITBLT )
01342 FT->pixel = (plD_pixel_fp) plD_pixelV_wingcc;
01343 else
01344 FT->pixel = (plD_pixel_fp) plD_pixel_wingcc;
01345 }
01346 #endif
01347
01348 pls->xdpi = GetDeviceCaps( dev->hdc, HORZRES ) / GetDeviceCaps( dev->hdc, HORZSIZE ) * 25.4;
01349 pls->ydpi = GetDeviceCaps( dev->hdc, VERTRES ) / GetDeviceCaps( dev->hdc, VERTSIZE ) * 25.4;
01350 plP_setpxl( dev->scale * pls->xdpi / 25.4, dev->scale * pls->ydpi / 25.4 );
01351 plP_setphy( 0, (PLINT) ( dev->scale * dev->width ), 0, (PLINT) ( dev->scale * dev->height ) );
01352 }
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 static void PrintPage( PLStream *pls )
01363 {
01364 wingcc_Dev *dev = (wingcc_Dev *) pls->dev;
01365 #ifdef HAVE_FREETYPE
01366 FT_Data *FT = (FT_Data *) pls->FT;
01367 #endif
01368 PRINTDLG Printer;
01369 DOCINFO docinfo;
01370
01371
01372
01373
01374
01375
01376 ZeroMemory( &docinfo, sizeof ( docinfo ) );
01377 docinfo.cbSize = sizeof ( docinfo );
01378 docinfo.lpszDocName = "Plplot Page";
01379
01380
01381
01382
01383
01384 ZeroMemory( &Printer, sizeof ( PRINTDLG ) );
01385 Printer.lStructSize = sizeof ( PRINTDLG );
01386 Printer.hwndOwner = dev->hwnd;
01387 Printer.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC;
01388 Printer.nCopies = 1;
01389
01390
01391
01392
01393
01394
01395
01396 if ( PrintDlg( &Printer ) != 0 )
01397 {
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407 if ( ( dev->push = GlobalAlloc( GMEM_ZEROINIT, sizeof ( wingcc_Dev ) ) ) != NULL )
01408 {
01409 BusyCursor();
01410 memcpy( dev->push, dev, sizeof ( wingcc_Dev ) );
01411
01412 dev->hdc = dev->PRNT_hdc = Printer.hDC;
01413
01414 UpdatePageMetrics( pls, 1 );
01415
01416 #ifdef HAVE_FREETYPE
01417 if ( FT )
01418 {
01419 dev->FT_smooth_text = FT->smooth_text;
01420 FT->smooth_text = 0;
01421 }
01422 #endif
01423
01424
01425
01426
01427
01428 StartDoc( dev->hdc, &docinfo );
01429 plRemakePlot( pls );
01430 EndDoc( dev->hdc );
01431
01432
01433
01434
01435
01436 dev->hdc = dev->SCRN_hdc;
01437 UpdatePageMetrics( pls, 0 );
01438
01439 #ifdef HAVE_FREETYPE
01440 if ( FT )
01441 {
01442 FT->smooth_text = dev->FT_smooth_text;
01443 }
01444 #endif
01445 memcpy( dev, dev->push, sizeof ( wingcc_Dev ) );
01446
01447 GlobalFree( dev->push );
01448 NormalCursor();
01449 RedrawWindow( dev->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW );
01450 }
01451 }
01452 }
01453
01454
01455
01456 #else
01457 int
01458 pldummy_wingcc()
01459 {
01460 return ( 0 );
01461 }
01462
01463 #endif // PLD_wingccdev