30 #if !defined ( __CYGWIN__ )    34 #define _T( a )    __TEXT( a )    43 #define ARRAY_SIZE( x )    ( ( sizeof x ) / ( sizeof *x ) )    44 #define INITIAL_HEAP_SIZE    16384  // Initial size of heap in bytes    80     struct _font_entry *next;       
    96     enum _dev_viewer viewer;
    98     enum _dev_state  state;             
    99     enum _dev_state  prev_state;        
   103         unsigned int status_bar : 1;
   104         unsigned int menu_bar   : 1;
   127 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_wingdi = 
"wingdi:Windows GDI:1:wingdi:11:wingdi\n";
   130 static int wingdi_streams = 0;
   133 static TCHAR      * frame_window_class_name = _T( 
"PLplotFrame" );
   134 static WNDCLASSEX frame_window_class;
   137 static TCHAR      * plot_area_class_name = _T( 
"PLplotArea" );
   138 static WNDCLASSEX plot_area_class;
   141 static HMENU plot_popup_menu;
   144 static HANDLE wingdi_heap;
   147 struct _font_entry *font_list = NULL;
   155 static void plD_line_wingdi( 
PLStream *, 
short, 
short, 
short, 
short );
   156 static void plD_polyline_wingdi( 
PLStream *, 
short *, 
short *, 
PLINT );
   157 static void plD_fill_polygon_wingdi( 
PLStream *
pls );
   160 static void plD_eop_wingdi( 
PLStream * );
   161 static void plD_bop_wingdi( 
PLStream * );
   162 static void plD_tidy_wingdi( 
PLStream * );
   163 static void plD_wait_wingdi( 
PLStream * );
   169     CommandPrint    = 0x08A1,
   170     CommandNextPage = 0x08A2,
   173 #define PlotAreaId     0x08F0   174 #define StatusBarId    0x08F1   178 #ifndef ENABLE_DYNDRIVERS   196 CrossHairCursor( 
struct wingdi_Dev * dev )
   200     cursor = LoadCursor( NULL, IDC_CROSS );
   201     SetClassLongPtr( dev->plot, GCL_HCURSOR, (
long) cursor );
   202     return SetCursor( cursor );
   206 NormalCursor( 
struct wingdi_Dev * dev )
   210     cursor = LoadCursor( NULL, IDC_ARROW );
   211     SetClassLongPtr( dev->plot, GCL_HCURSOR, (LONG_PTR) cursor );
   216 BusyCursor( 
struct wingdi_Dev * dev )
   220     cursor = LoadCursor( NULL, IDC_WAIT );
   221     SetClassLongPtr( dev->plot, GCL_HCURSOR, (LONG_PTR) cursor );
   226 update_status_bar( 
struct wingdi_Dev * dev )
   228     LPSTR status_text[] =
   237     if ( dev->status_bar == NULL )
   240     SendMessage( dev->status_bar,
   243         (LPARAM) status_text[dev->state] );
   254 static void UpdatePageMetrics( 
PLStream *
pls, 
enum _dev_type dev_type )
   256     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
   258     dev->type = dev_type;
   259     if ( dev_type == DEV_PRINTER )
   263         PLFLT plot_aspect, print_aspect;
   264         hsize = GetDeviceCaps( dev->hdc, HORZRES );
   265         vsize = GetDeviceCaps( dev->hdc, VERTRES );
   269         plot_aspect  = (
PLFLT) dev->width / (
PLFLT) dev->height;
   271         if ( plot_aspect > 1.0 )
   275             dev->height = (
PLINT) ( (
PLFLT) hsize / plot_aspect );
   280             dev->width  = (
PLINT) ( (
PLFLT) vsize * plot_aspect );
   288         GetClientRect( dev->plot, &rect );
   289         dev->width  = rect.right;
   290         dev->height = rect.bottom;
   292         pldebug( 
"wingdi", 
"Page size [%d %d] [%d %d]\n",
   294             rect.right, rect.bottom );
   304     pldebug( 
"wingdi", 
"Scale = (%f %f) (FLT)\n",
   305         dev->xscale, dev->yscale );
   310     pldebug( 
"wingdi", 
"Original xdpi = %f ydpi = %f\n",
   318     pls->
xdpi  = GetDeviceCaps( dev->hdc, LOGPIXELSX );
   319     dev->xdpmm = pls->
xdpi / 25.4;
   320     pls->
ydpi  = GetDeviceCaps( dev->hdc, LOGPIXELSY );
   321     dev->ydpmm = pls->
ydpi / 25.4;
   323     pldebug( 
"wingdi", 
"New xdpi = %f ydpi = %f\n",
   325     pldebug( 
"wingdi", 
"Windows reports xdpi = %d ydpi = %d\n",
   326         GetDeviceCaps( dev->hdc, LOGPIXELSX ),
   327         GetDeviceCaps( dev->hdc, LOGPIXELSY ) );
   331         dev->yscale * pls->
ydpi / 25.4 );
   346 static void PrintPage( 
PLStream *pls )
   348     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
   352     struct wingdi_Dev *push;      
   356     ZeroMemory( &docinfo, 
sizeof ( docinfo ) );
   357     docinfo.cbSize      = 
sizeof ( docinfo );
   358     docinfo.lpszDocName = _T( 
"Plplot Page" );
   363     hDevMode = GlobalAlloc( GHND, 
sizeof ( DEVMODE ) );
   364     if ( hDevMode == NULL )
   366         plwarn( 
"wingdi:  Failed to allocate memory for printer defaults\n" );
   369     ZeroMemory( hDevMode, 
sizeof ( DEVMODE ) );
   370     hDevMode->dmSpecVersion = DM_SPECVERSION;
   371     hDevMode->dmSize        = 
sizeof ( DEVMODE );
   372     hDevMode->dmFields      = DM_ORIENTATION;
   373     hDevMode->dmOrientation = DMORIENT_LANDSCAPE;
   376     ZeroMemory( &Printer, 
sizeof ( PRINTDLGEX ) );
   377     Printer.lStructSize = 
sizeof ( PRINTDLGEX );
   378     Printer.hwndOwner   = dev->plot;
   379     Printer.hDevMode    = hDevMode;
   382     Printer.Flags = PD_NOPAGENUMS | PD_NOCURRENTPAGE | PD_NOSELECTION
   383                     | PD_COLLATE | PD_RETURNDC;
   390     Printer.nPageRanges    = 0;
   391     Printer.nMaxPageRanges = 0;
   392     Printer.lpPageRanges   = NULL;
   393     Printer.nMinPage       = 0;
   394     Printer.nMaxPage       = 0;
   399     Printer.nStartPage = START_PAGE_GENERAL;
   404     if ( PrintDlgEx( &Printer ) == S_OK
   405          && Printer.dwResultAction == PD_RESULT_PRINT )
   413         push = HeapAlloc( wingdi_heap, 0, 
sizeof ( 
struct wingdi_Dev ) );
   419             memcpy( push, dev, 
sizeof ( 
struct wingdi_Dev ) );
   422             dev->hdc = Printer.hDC;
   423             UpdatePageMetrics( pls, DEV_PRINTER );
   426             StartDoc( dev->hdc, &docinfo );
   431             memcpy( dev, push, 
sizeof ( 
struct wingdi_Dev ) );
   432             UpdatePageMetrics( pls, DEV_WINDOW );
   434             HeapFree( wingdi_heap, 0, push );
   445             plwarn( 
"wingdi: Unable to save state for print" );
   450     if ( Printer.hDC != NULL )
   451         DeleteDC( Printer.hDC );
   452     if ( Printer.hDevMode != NULL )
   453         DeleteDC( Printer.hDevMode );
   454     if ( Printer.hDevNames != NULL )
   455         DeleteDC( Printer.hDevNames );
   458         GlobalFree( hDevMode );
   462 wait_for_user_input( 
PLStream *pls )
   464     struct wingdi_Dev * dev = (
struct wingdi_Dev *) pls->
dev;
   467     pldebug( 
"wingdi", 
"Waiting for user input\n" );
   470     dev->state = DEV_WAITING;
   471     update_status_bar( dev );
   474     while ( GetMessage( &msg, NULL, 0, 0 ) && dev->state != DEV_ACTIVE )
   476         TranslateMessage( &msg );
   477         switch ( (
int) msg.message )
   481             TrackPopupMenu( plot_popup_menu,
   482                 TPM_CENTERALIGN | TPM_RIGHTBUTTON,
   483                 LOWORD( msg.lParam ),
   484                 HIWORD( msg.lParam ),
   491             if ( ( (TCHAR) ( msg.wParam ) == 32 ) ||
   492                  ( (TCHAR) ( msg.wParam ) == 13 ) )
   494                 dev->state = DEV_ACTIVE;
   495                 update_status_bar( dev );
   497             else if ( ( (TCHAR) ( msg.wParam ) == 27 ) ||
   498                       ( (TCHAR) ( msg.wParam ) == 
'q' ) ||
   499                       ( (TCHAR) ( msg.wParam ) == 
'Q' ) )
   501                 dev->state = DEV_ACTIVE;
   502                 update_status_bar( dev );
   503                 PostQuitMessage( 0 );
   507         case WM_LBUTTONDBLCLK:
   508             pldebug( 
"wingdi", 
"WM_LBUTTONDBLCLK\n" );
   509             dev->state = DEV_ACTIVE;
   510             update_status_bar( dev );
   514             switch ( LOWORD( msg.wParam ) )
   517                 pldebug( 
"wingdi", 
"CommandPrint\n" );
   520             case CommandNextPage:
   521                 pldebug( 
"wingdi", 
"CommandNextPage\n" );
   522                 dev->state = DEV_ACTIVE;
   523                 update_status_bar( dev );
   526                 pldebug( 
"wingdi", 
"CommandQuit\n" );
   527                 dev->state = DEV_ACTIVE;
   528                 update_status_bar( dev );
   529                 PostQuitMessage( 0 );
   535             DispatchMessage( &msg );
   540     pldebug( 
"wingdi", 
"Done waiting\n" );
   541     dev->state = DEV_ACTIVE;
   553     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
   559     previous = CrossHairCursor( dev );
   561     while ( gin->
pX < 0 )
   563         GetMessage( &msg, NULL, 0, 0 );
   564         TranslateMessage( &msg );
   565         switch ( (
int) msg.message )
   570             gin->
dX = (
PLFLT) gin->
pX / ( dev->width - 1 );
   571             gin->
dY = 1.0 - (
PLFLT) gin->
pY / ( dev->height - 1 );
   573             if ( msg.wParam & MK_LBUTTON )
   575                 pldebug( 
"wingdi", 
"Left button down\n" );
   581             else if ( msg.wParam & MK_MBUTTON )
   583                 pldebug( 
"wingdi", 
"Middle button down\n" );
   588             else if ( msg.wParam & MK_RBUTTON )
   590                 pldebug( 
"wingdi", 
"Right button down\n" );
   600             gin->
dX = (
PLFLT) gin->
pX / ( dev->width - 1 );
   601             gin->
dY = 1.0 - (
PLFLT) gin->
pY / ( dev->height - 1 );
   603             if ( msg.wParam & MK_LBUTTON )
   605                 pldebug( 
"wingdi", 
"Left button up\n" );
   610             else if ( msg.wParam & MK_MBUTTON )
   612                 pldebug( 
"wingdi", 
"Middle button up\n" );
   615                 gin->
state  = 0x10000;
   617             else if ( msg.wParam & MK_RBUTTON )
   619                 pldebug( 
"wingdi", 
"Right button up\n" );
   629             gin->
dX = (
PLFLT) gin->
pX / ( dev->width - 1 );
   630             gin->
dY = 1.0 - (
PLFLT) gin->
pY / ( dev->height - 1 );
   641     SetCursor( previous );
   650 static void CopySCRtoBMP( 
PLStream *pls )
   652     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
   657     if ( dev->hdc_bmp != NULL )
   658         DeleteDC( dev->hdc_bmp );
   659     if ( dev->bitmap != NULL )
   660         DeleteObject( dev->bitmap );
   662     dev->hdc_bmp = CreateCompatibleDC( dev->hdc );
   663     GetClientRect( dev->plot, &rect );
   664     dev->bitmap = CreateCompatibleBitmap( dev->hdc,
   665         rect.right, rect.bottom );
   666     previous = SelectObject( dev->hdc_bmp, dev->bitmap );
   667     BitBlt( dev->hdc_bmp, 0, 0, rect.right, rect.bottom, dev->hdc, 0, 0, SRCCOPY );
   668     SelectObject( dev->hdc_bmp, previous );
   679     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
   680     COLORREF          previous_color;
   683     pldebug( 
"wingdi", 
"  Erasing window\n" );
   689     if ( dev->type == DEV_WINDOW )
   692         GetClientRect( dev->plot, &rect );
   693         previous_color = SetBkColor( dev->hdc,
   695         ExtTextOut( dev->hdc, 0, 0, ETO_OPAQUE, &rect, _T( 
"" ), 0, 0 );
   696         SetBkColor( dev->hdc, previous_color );
   702         rect.right  = GetDeviceCaps( dev->hdc, HORZRES );
   703         rect.bottom = GetDeviceCaps( dev->hdc, VERTRES );
   717     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
   719     enum _dev_state   current;
   721     pldebug( 
"wingdi", 
"Resizing\n" );
   724     if ( dev->state == DEV_WAITING
   725          || dev->state == DEV_ACTIVE
   726          || dev->state == DEV_DRAWING )
   728         GetClientRect( dev->plot, &rect );
   729         pldebug( 
"wingdi", 
"  Size = [%d %d] [%d %d]\n",
   731             rect.right, rect.bottom );
   734         if ( ( rect.right > 0 ) && ( rect.bottom > 0 ) )
   736             UpdatePageMetrics( pls, DEV_WINDOW );
   740             current = dev->state;
   742             dev->state = current;
   743             update_status_bar( dev );
   748         pldebug( 
"wingdi", 
"  No action taken, state = %d\n", dev->state );
   750     pldebug( 
"wingdi", 
"Resizing done\n" );
   756 LRESULT CALLBACK PlplotFrameProc(
   762     struct wingdi_Dev *dev = NULL;
   766     dev = (
struct wingdi_Dev *) GetWindowLongPtr( hwnd, GWLP_USERDATA );
   768     dev = (
struct wingdi_Dev *) GetWindowLongPtr( hwnd, GWL_USERDATA );
   779         hStatus = CreateWindowEx(
   783             WS_CHILD | WS_VISIBLE,
   787             GetModuleHandle( NULL ),
   789         if ( hStatus != NULL )
   791             int status_widths[] = { 100, 200, 300, -1 };
   793             SendMessage( hStatus, SB_SETPARTS,
   794                 (WPARAM) ARRAY_SIZE( status_widths ),
   795                 (LPARAM) status_widths );
   796             SendMessage( hStatus, SB_SETTEXT,
   798                 (LPARAM) (LPSTR) TEXT( 
"Active" ) );
   802             MessageBox( hwnd, 
"Could not create status bar.",
   803                 "Error", MB_OK | MB_ICONERROR );
   813         RECT rStatus, rFrame;
   817         GetClientRect( hwnd, &rFrame );
   820         hStatus = GetDlgItem( hwnd, StatusBarId );
   821         SendMessage( hStatus, WM_SIZE, 0, 0 );
   822         GetWindowRect( hStatus, &rStatus );
   825         hPlot       = GetDlgItem( hwnd, PlotAreaId );
   826         plot_height = rFrame.bottom - ( rStatus.bottom - rStatus.top );
   830             rFrame.right, plot_height,
   831             SWP_NOZORDER | SWP_SHOWWINDOW );
   843         return DefWindowProc( hwnd, uMsg, wParam, lParam );
   854 LRESULT CALLBACK PlplotPlotAreaProc( HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
   857     struct wingdi_Dev *dev = NULL;
   861     if ( nMsg == WM_CREATE )
   869     pls = (
PLStream *) GetWindowLongPtr( hwnd, GWLP_USERDATA );
   871     pls = (
PLStream *) GetWindowLongPtr( hwnd, GWL_USERDATA );
   878         return DefWindowProc( hwnd, nMsg, wParam, lParam );
   881     dev = (
struct wingdi_Dev *) pls->
dev;
   896         pldebug( 
"wingdi", 
"WM_DESTROY\n" );
   897         PostQuitMessage( 0 );
   909         pldebug( 
"wingdi", 
"WM_PAINT state = %d\n", dev->state );
   915         if ( GetUpdateRect( dev->plot, NULL, 
FALSE ) )
   922             BeginPaint( dev->plot, &ps );
   924             pldebug( 
"wingdi", 
"  Need to redraw area (%d,%d) (%d,%d)\n",
   925                 ps.rcPaint.left, ps.rcPaint.top,
   926                 ps.rcPaint.right, ps.rcPaint.bottom );
   927             pldebug( 
"wingdi", 
"  Erase status = %d\n", ps.fErase );
   928             pldebug( 
"wingdi", 
"  Device state = %d\n", dev->state );
   936             if ( dev->bitmap != NULL && dev->state != DEV_DRAWING )
   939                 pldebug( 
"wingdi", 
"  Blit image\n" );
   940                 previous = SelectObject( dev->hdc_bmp, dev->bitmap );
   942                     ps.rcPaint.left, ps.rcPaint.top,
   943                     ps.rcPaint.right, ps.rcPaint.bottom,
   945                     ps.rcPaint.left, ps.rcPaint.top,
   947                 SelectObject( dev->hdc_bmp, previous );
   952                     "  No paint action bitmap = %lx state = \n",
   953                     dev->bitmap, dev->state );
   956             EndPaint( dev->plot, &ps );
   961             pldebug( 
"wingdi", 
"  No update area to paint\n" );
   963         pldebug( 
"wingdi", 
"WM_PAINT exit\n" );
   969         pldebug( 
"wingdi", 
"WM_SIZE wParam = %d\n", wParam );
   972         if ( wParam == SIZE_MAXIMIZED )
   975             pldebug( 
"wingdi", 
"  Window maximized\n" );
   978         else if ( dev->state == DEV_SIZEMOVE )
   982             pldebug( 
"wingdi", 
"  Window size/moved\n" );
   986             dev->state = DEV_RESIZE;
   987             pldebug( 
"wingdi", 
"  New state %d\n", dev->state );
   988             update_status_bar( dev );
   990         else if ( wParam == SIZE_RESTORED )
   995             pldebug( 
"wingdi", 
"  Window restored\n" );
  1000             pldebug( 
"wingdi", 
"  Unknowing sizing action\n" );
  1002         pldebug( 
"wingdi", 
"WM_SIZE exit\n" );
  1007     case WM_ENTERSIZEMOVE:
  1008         pldebug( 
"wingdi", 
"WM_ENTERSIZEMOVE\n" );
  1009         pldebug( 
"wingdi", 
"  Save state %d\n", dev->state );
  1010         dev->prev_state = dev->state;
  1012         dev->state = DEV_SIZEMOVE;
  1013         update_status_bar( dev );
  1017     case WM_EXITSIZEMOVE:
  1018         pldebug( 
"wingdi", 
"WM_EXITSIZEMOVE\n" );
  1021         if ( dev->state == DEV_RESIZE || dev->state == DEV_SIZEMOVE )
  1023             pldebug( 
"wingdi", 
"  Restore state %d\n", dev->prev_state );
  1027             dev->state = dev->prev_state;
  1028             update_status_bar( dev );
  1039         pldebug( 
"wingdi", 
"WM_ERASEBKGND state = %d\n", dev->state );
  1041         if ( dev->state != DEV_WAITING )
  1049         pldebug( 
"wingdi", 
"  No erase action taken\n" );
  1059         xw = GET_X_LPARAM( lParam );
  1060         yw = GET_Y_LPARAM( lParam );
  1061         x  = (double) xw * dev->xscale;
  1062         y  = (
double) ( dev->height - yw ) * dev->yscale;
  1064         snprintf( mesg, 
sizeof ( mesg ), 
"%5.1lf", x );
  1065         if ( dev->status_bar != NULL )
  1066             SendMessage( dev->status_bar,
  1071         snprintf( mesg, 
sizeof ( mesg ), 
"%5.1lf", y );
  1072         if ( dev->status_bar != NULL )
  1073             SendMessage( dev->status_bar,
  1084         pldebug( 
"wingdi", 
"WM_COMMAND\n" );
  1091     return DefWindowProc( hwnd, nMsg, wParam, lParam );
  1101 wingdi_module_initialize( 
void )
  1103     INITCOMMONCONTROLSEX init_controls;
  1110     if ( wingdi_streams++ > 0 )
  1113     pldebug( 
"wingdi", 
"module init\n" );
  1116     init_controls.dwSize = 
sizeof ( INITCOMMONCONTROLSEX );
  1117     init_controls.dwICC  = ICC_BAR_CLASSES;
  1118     if ( !InitCommonControlsEx( &init_controls ) )
  1120         plwarn( 
"wingdi:  Failed to initialize common Window controls\n" );
  1128     memset( &frame_window_class, 0, 
sizeof ( WNDCLASSEX ) );
  1131     frame_window_class.lpszClassName = frame_window_class_name;
  1135     frame_window_class.cbSize = 
sizeof ( WNDCLASSEX );
  1138     frame_window_class.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS
  1142     frame_window_class.lpfnWndProc = PlplotFrameProc;
  1145     frame_window_class.hInstance = GetModuleHandle( NULL );
  1148     frame_window_class.hIcon   = LoadIcon( NULL, IDI_APPLICATION );
  1149     frame_window_class.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
  1150     frame_window_class.hCursor = LoadCursor( NULL, IDC_ARROW );
  1153     frame_window_class.hbrBackground = (HBRUSH) COLOR_WINDOW;
  1156     frame_window_class.cbWndExtra = 
sizeof ( 
struct wingdi_Dev * );
  1159     RegisterClassEx( &frame_window_class );
  1166     memset( &plot_area_class, 0, 
sizeof ( WNDCLASSEX ) );
  1169     plot_area_class.lpszClassName = plot_area_class_name;
  1173     plot_area_class.cbSize = 
sizeof ( WNDCLASSEX );
  1176     plot_area_class.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS
  1180     plot_area_class.lpfnWndProc = PlplotPlotAreaProc;
  1183     plot_area_class.hInstance = GetModuleHandle( NULL );
  1186     plot_area_class.hIcon   = LoadIcon( NULL, IDI_APPLICATION );
  1187     plot_area_class.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
  1188     plot_area_class.hCursor = LoadCursor( NULL, IDC_ARROW );
  1191     plot_area_class.hbrBackground = NULL;
  1195     plot_area_class.cbWndExtra = 
sizeof ( 
PLStream * );
  1198     RegisterClassEx( &plot_area_class );
  1203     plot_popup_menu = CreatePopupMenu();
  1204     AppendMenu( plot_popup_menu, MF_STRING, CommandPrint, _T( 
"Print" ) );
  1205     AppendMenu( plot_popup_menu, MF_STRING, CommandNextPage, _T( 
"Next Page" ) );
  1206     AppendMenu( plot_popup_menu, MF_STRING, CommandQuit, _T( 
"Quit" ) );
  1214     wingdi_heap = HeapCreate( 0, INITIAL_HEAP_SIZE, 0 );
  1215     if ( wingdi_heap == NULL )
  1219         plexit( 
"wingdi: Unable to allocate heap" );
  1223 static void wingdi_module_cleanup( 
void )
  1225     struct _font_entry *ptr;
  1228     if ( wingdi_streams > 0 )
  1231     DeleteMenu( plot_popup_menu, CommandPrint, 0 );
  1232     DeleteMenu( plot_popup_menu, CommandNextPage, 0 );
  1233     DeleteMenu( plot_popup_menu, CommandQuit, 0 );
  1234     DestroyMenu( plot_popup_menu );
  1236     if ( !UnregisterClass( plot_area_class_name, plot_area_class.hInstance ) )
  1238         plexit( 
"wingdi: Failed to unregister window class" );
  1240     if ( !UnregisterClass( frame_window_class_name, frame_window_class.hInstance ) )
  1242         plexit( 
"wingdi: Failed to unregister window class" );
  1245     while ( font_list != NULL )
  1248         DeleteObject( ptr->font );
  1249         font_list = ptr->next;
  1250         HeapFree( wingdi_heap, 0, ptr );
  1253     if ( HeapDestroy( wingdi_heap ) == 0 )
  1255         plexit( 
"wingdi: Failed to destroy heap" );
  1268     struct wingdi_Dev *dev;
  1270     int    full_viewer      = 0; 
  1271     DrvOpt wingdi_options[] = {
  1272         { 
"full",      
DRV_INT, &full_viewer, 
"Enable full function viewer (0|1)" },
  1273         { 
"statusbar", 
DRV_INT, &status_bar,  
"Enable status bar (0|1)"           },
  1282     pldebug( 
"wingdi", 
"Device Init\n" );
  1285     wingdi_module_initialize();
  1288     if ( pls->
dev != NULL )
  1289         free( (
void *) pls->
dev );
  1291     pls->
dev = calloc( 1, (
size_t) 
sizeof ( 
struct wingdi_Dev ) );
  1292     if ( pls->
dev == NULL )
  1293         plexit( 
"plD_init_wingdi_Dev: Out of memory." );
  1296     dev = (
struct wingdi_Dev *) pls->
dev;
  1318         dev->viewer = VIEWER_FULL;
  1320         dev->viewer = VIEWER_MINIMAL;
  1324         dev->feature.status_bar = 1;
  1326         dev->feature.status_bar = 0;
  1334         plspage( 0., 0., 800, 600, 0, 0 );
  1337     dev->width  = pls->
xlength - 1;     
  1338     dev->height = pls->
ylength - 1;
  1342     programlength = strlen( pls->
program ) + 1;
  1343     program       = malloc( programlength * 
sizeof ( TCHAR ) );
  1344     MultiByteToWideChar( CP_UTF8, 0, pls->
program, programlength, program, programlength );
  1349     if ( dev->viewer == VIEWER_FULL )
  1352         dev->frame = CreateWindowEx(
  1353             WS_EX_WINDOWEDGE + WS_EX_LEFT,
  1354             frame_window_class_name,                   
  1364             frame_window_class.hInstance,              
  1369         dev->plot = CreateWindowEx(
  1371             plot_area_class_name,                      
  1373             WS_CHILD | WS_VISIBLE,                     
  1377             plot_area_class.hInstance,                 
  1384         dev->plot = CreateWindowEx(
  1385             WS_EX_WINDOWEDGE + WS_EX_LEFT,
  1386             plot_area_class_name,                      
  1396             plot_area_class.hInstance,                 
  1401     if ( dev->plot == NULL )
  1403         plexit( 
"wingdi:  Failed to create plot area\n" );
  1414     SetWindowLongPtr( dev->plot, GWLP_USERDATA, (LONG_PTR) pls );
  1416         SetWindowLongPtr( dev->frame, GWLP_USERDATA, (LONG_PTR) dev );
  1418     SetWindowLongPtr( dev->plot, GWL_USERDATA, (LONG) pls );
  1420         SetWindowLongPtr( dev->frame, GWL_USERDATA, (LONG) dev );
  1424     dev->hdc = GetDC( dev->plot );
  1432     if ( dev->viewer == VIEWER_FULL )
  1434         ShowWindow( dev->frame, SW_SHOWDEFAULT );
  1435         SetForegroundWindow( dev->frame );
  1439         ShowWindow( dev->plot, SW_SHOWDEFAULT );
  1440         SetForegroundWindow( dev->plot );
  1443     if ( dev->feature.status_bar )
  1447         dev->status_bar = GetDlgItem( dev->frame, StatusBarId );
  1454     UpdatePageMetrics( pls, DEV_WINDOW );
  1459         SetPolyFillMode( dev->hdc, ALTERNATE );
  1461         SetPolyFillMode( dev->hdc, WINDING );
  1467     dev->state = DEV_ACTIVE;
  1468     update_status_bar( dev );
  1478 plD_line_wingdi( 
PLStream *pls, 
short x1a, 
short y1a, 
short x2a, 
short y2a )
  1480     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  1481     HGDIOBJ           previous_obj;
  1484     points[0].x = (LONG) ( x1a / dev->xscale );
  1485     points[1].x = (LONG) ( x2a / dev->xscale );
  1486     points[0].y = (LONG) ( dev->height - ( y1a / dev->yscale ) );
  1487     points[1].y = (LONG) ( dev->height - ( y2a / dev->yscale ) );
  1489     previous_obj = SelectObject( dev->hdc, dev->pen );
  1491     if ( points[0].x != points[1].x || points[0].y != points[1].y )
  1493         Polyline( dev->hdc, points, 2 );
  1497         SetPixel( dev->hdc, points[0].x, points[0].y, dev->color );
  1499     SelectObject( dev->hdc, previous_obj );
  1509 plD_polyline_wingdi( 
PLStream *pls, 
short *xa, 
short *ya, 
PLINT npts )
  1511     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  1513     POINT             *points = NULL;
  1514     HGDIOBJ           previous_obj;
  1518         points = HeapAlloc( wingdi_heap, HEAP_ZERO_MEMORY,
  1519             (
size_t) npts * 
sizeof ( POINT ) );
  1520         if ( points != NULL )
  1522             for ( i = 0; i < npts; i++ )
  1524                 points[i].x = (LONG) ( xa[i] / dev->xscale );
  1525                 points[i].y = (LONG) ( dev->height - ( ya[i] / dev->yscale ) );
  1528             previous_obj = SelectObject( dev->hdc, dev->pen );
  1529             Polyline( dev->hdc, points, npts );
  1530             SelectObject( dev->hdc, previous_obj );
  1531             HeapFree( wingdi_heap, 0, points );
  1535             plexit( 
"Could not allocate memory to \"plD_polyline_wingdi\"\n" );
  1546 plD_fill_polygon_wingdi( 
PLStream *pls )
  1548     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  1550     POINT             *points = NULL;
  1551     HGDIOBJ           previous_brush, previous_pen;
  1559     points = HeapAlloc( wingdi_heap, HEAP_ZERO_MEMORY,
  1560         (
size_t) pls->
dev_npts * sizeof ( POINT ) );
  1562     if ( points == NULL )
  1563         plexit( 
"Could not allocate memory to \"plD_fill_polygon_wingdi\"\n" );
  1565     for ( i = 0; i < pls->
dev_npts; i++ )
  1567         points[i].x = (
PLINT) ( pls->
dev_x[i] / dev->xscale );
  1568         points[i].y = (
PLINT) ( dev->height - ( pls->
dev_y[i] / dev->yscale ) );
  1572     fillbrush      = CreateSolidBrush( dev->color );
  1573     hpen           = CreatePen( PS_SOLID, 1, dev->color );
  1574     previous_brush = SelectObject( dev->hdc, fillbrush );
  1575     previous_pen   = SelectObject( dev->hdc, hpen );
  1578     Polygon( dev->hdc, points, pls->
dev_npts );
  1581     SelectObject( dev->hdc, previous_brush );
  1582     DeleteObject( fillbrush );
  1583     SelectObject( dev->hdc, previous_pen );
  1584     DeleteObject( hpen );
  1586     HeapFree( wingdi_heap, 0, points );
  1597     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  1598     COLORREF          previous_color;
  1601     if ( x1 >= 0 && y1 >= 0 && x2 >= 0 && y2 >= 0 )
  1603         rect.left   = (LONG) ( x1 / dev->xscale );
  1604         rect.top    = (LONG) ( dev->height - ( y1 / dev->yscale ) );
  1605         rect.right  = (LONG) ( x2 / dev->xscale );
  1606         rect.bottom = (LONG) ( dev->height - ( y2 / dev->yscale ) );
  1611         GetClientRect( dev->plot, &rect );
  1617     previous_color = SetBkColor( dev->hdc,
  1619     ExtTextOut( dev->hdc, 0, 0, ETO_OPAQUE, &rect, _T( 
"" ), 0, 0 );
  1620     SetBkColor( dev->hdc, previous_color );
  1634     PLFLT rotation, shear, stride;
  1638     PLFLT old_sscale, sscale;
  1639     PLFLT old_soffset, soffset;
  1649 set_font( 
struct wingdi_Dev * dev,
  1650           LONG font_height, LONG escapement,
  1651           LONG weight, BYTE italic,
  1653           BYTE pitch, BYTE family )
  1655     struct _font_entry *ptr = font_list;
  1657     for ( ptr = font_list; ptr != NULL; ptr = ptr->next )
  1660             ptr->info.lfHeight == font_height
  1661             && ptr->info.lfEscapement == escapement
  1662             && ptr->info.lfWeight == weight
  1663             && ptr->info.lfItalic == italic
  1664             && ptr->info.lfCharSet == charset
  1665             && ptr->info.lfPitchAndFamily == ( pitch | family )
  1666             && ptr->hdc == dev->hdc
  1669             return SelectObject( dev->hdc, ptr->font );
  1674     ptr = HeapAlloc( wingdi_heap, 0, 
sizeof ( 
struct _font_entry ) );
  1677     ptr->info.lfHeight         = font_height;
  1678     ptr->info.lfWidth          = 0;
  1679     ptr->info.lfEscapement     = escapement;  
  1680     ptr->info.lfOrientation    = 0;           
  1681     ptr->info.lfWeight         = weight;      
  1682     ptr->info.lfItalic         = italic;
  1683     ptr->info.lfUnderline      = 0;
  1684     ptr->info.lfStrikeOut      = 0;
  1685     ptr->info.lfCharSet        = charset;
  1686     ptr->info.lfOutPrecision   = OUT_OUTLINE_PRECIS;
  1687     ptr->info.lfClipPrecision  = CLIP_DEFAULT_PRECIS;
  1688     ptr->info.lfQuality        = ANTIALIASED_QUALITY;
  1689     ptr->info.lfPitchAndFamily = pitch | family;
  1690     ptr->font = CreateFontIndirect( &( ptr->info ) );
  1691     ptr->hdc  = dev->hdc;
  1694     if ( ptr->font == NULL )
  1696         plwarn( 
"wingdi:  Unable to create a font, using default\n" );
  1697         HeapFree( wingdi_heap, 0, ptr );
  1702         if ( font_list != NULL )
  1704             ptr->next = font_list;
  1713     return SelectObject( dev->hdc, ptr->font );
  1718 static const char hershey_to_ansi_lookup[] =
  1720     0,     0,    0,   0,   0,   0,   0,   0,   0, 0,         
  1721     0,     0,    0,   0,   0,   0,   0,   0,   0, 0,         
  1722     0,     0,    0,   0,   0,   0,   0,   0,   0, 0,         
  1723     0,     0,    0, 
'!', 
'"', 
'#', 
'$', 
'%', 
'&', 
'\'',      
  1724     '(', 
')', 
'*',  
'+', 
',', 
'-', 
'.', 
'/', 
'0', 
'1',       
  1725     '2', 
'3', 
'4',  
'5', 
'6', 
'7', 
'8', 
'9', 
':', 
';',       
  1726     '<', 
'=', 
'>',  
'?', 
'@', 
'A', 
'B', 
'C', 
'D', 
'E',       
  1727     'F', 
'G', 
'H',  
'I', 
'J', 
'K', 
'L', 
'M', 
'N', 
'O',       
  1728     'P', 
'Q', 
'R',  
'S', 
'T', 
'U', 
'V', 
'W', 
'X', 
'Y',       
  1729     'Z', 
'[', 
'\\', 
']', 
'^', 
'_', 
'`', 
'a', 
'b', 
'c',       
  1730     'd', 
'e', 
'f',  
'g', 
'h', 
'i', 
'j', 
'k', 
'l', 
'm',       
  1731     'n', 
'o', 
'p',  
'q', 
'r', 
's', 
't', 
'u', 
'v', 
'w',       
  1732     'x', 
'y', 
'z',  
'{', 
'|', 
'}', 
'~',   0,   0, 0,         
  1734 static const char hershey_to_symbol_lookup[] =
  1736     0,    0xB7, 0x2B, 0x2A, 0, 0, 0, 0,    0, 0,                
  1737     0,       0,    0,    0, 0, 0, 0, 0,    0, 0,                
  1738     0,       0,    0,    0, 0, 0, 0, 0, 0xAC, 0xAE,             
  1743 process_text_escape( 
struct wingdi_Dev *dev, 
EscText *args,
  1744                      int *i, 
char *
buffer, 
int *j,
  1745                      struct _text_state *state )
  1750     switch ( args->
string[++( *i )] )
  1754             &state->old_sscale, &state->sscale,
  1755             &state->old_soffset, &state->soffset );
  1758             (LONG) ( state->font_height * state->sscale ),
  1759             (LONG) ( state->rotation ),
  1762             state->font_charset,
  1763             state->font_pitch, state->font_family );
  1767             &state->old_sscale, &state->sscale,
  1768             &state->old_soffset, &state->soffset );
  1771             (LONG) ( state->font_height * state->sscale ),
  1772             (LONG) ( state->rotation ),
  1775             state->font_charset,
  1776             state->font_pitch, state->font_family );
  1779         switch ( args->
string[++( *i )] )
  1782             state->font_family  = FF_SWISS;
  1784             state->font_charset = ANSI_CHARSET;
  1787             state->font_family  = FF_ROMAN;
  1789             state->font_charset = ANSI_CHARSET;
  1792             state->font_family  = FF_ROMAN;
  1794             state->font_charset = ANSI_CHARSET;
  1797             state->font_family  = FF_SCRIPT;
  1799             state->font_charset = ANSI_CHARSET;
  1803             (LONG) ( state->font_height * state->sscale ),
  1804             (LONG) ( state->rotation ),
  1807             state->font_charset,
  1808             state->font_pitch, state->font_family );
  1811         state->font_family  = FF_DONTCARE;
  1813         state->font_charset = GREEK_CHARSET;
  1816             (LONG) ( state->font_height * state->sscale ),
  1817             (LONG) ( state->rotation ),
  1820             state->font_charset,
  1821             state->font_pitch, state->font_family );
  1824         sscanf( args->
string + *i, 
"%d", &val );
  1826         if ( val > 0 && val < ARRAY_SIZE( hershey_to_ansi_lookup )
  1827              && hershey_to_ansi_lookup[val] != 0 )
  1829             buffer[( *j )++] = hershey_to_ansi_lookup[val];
  1833             plwarn( 
"Unsupported hershey character\n" );
  1835             buffer[( *j )++] = 0x95;
  1840         plwarn( 
"Unicode characters are not supported\n" );
  1844         plwarn( 
"Ignoring escape code %c\n" );
  1857     struct wingdi_Dev  *dev = (
struct wingdi_Dev *) pls->
dev;
  1858     struct _text_state state;
  1859     PLFLT    cos_rot, sin_rot;
  1860     PLFLT    cos_shear, sin_shear;
  1862     UINT     halign, valign;
  1863     HFONT    font = NULL, prev_font = NULL;
  1864     COLORREF prev_color;
  1874     state.font_weight  = FW_NORMAL;
  1875     state.font_charset = ANSI_CHARSET;
  1876     state.font_pitch   = DEFAULT_PITCH;
  1877     state.font_family  = FF_DONTCARE;
  1878     switch ( pls->
cfont )
  1882         state.font_family = FF_SWISS;
  1886         state.font_family = FF_ROMAN;
  1890         state.font_family = FF_ROMAN;
  1895         state.font_family = FF_SCRIPT;
  1900     state.font_height = 1.6 * pls->
chrht * dev->ydpmm;
  1903         &state.rotation, &state.shear, &state.stride );
  1904     state.rotation -= pls->
diorot * 
PI / 2.0;
  1905     cos_rot         = (
PLFLT) cos( state.rotation );
  1906     sin_rot         = (
PLFLT) sin( state.rotation );
  1907     cos_shear       = (
PLFLT) cos( state.shear );
  1908     sin_shear       = (
PLFLT) sin( state.shear );
  1911     state.rotation = state.rotation * ( 180.0 / 
M_PI ) * 10.0;
  1919         PLFLT cos_theta, sin_theta;
  1926         cos_theta = cos( -pls->
diorot * 
PI / 2.0 );
  1927         sin_theta = sin( -pls->
diorot * 
PI / 2.0 );
  1928         x         = cos_theta * (
PLFLT) ox - sin_theta * (
PLFLT) oy;
  1929         y         = sin_theta * (
PLFLT) ox + cos_theta * (
PLFLT) oy;
  1936         rx = (int) ( x / dev->xscale );
  1937         ry = (int) ( dev->height - ( y / dev->yscale ) );
  1941         rx = (int) ( args->
x / dev->xscale );
  1942         ry = (int) ( dev->height - ( args->
y / dev->yscale ) );
  1949     if ( args->
base == 2 )
  1954     else if ( args->
base == 1 )
  1965         ry -= (int) ( 0.5 * pls->
chrht * dev->ydpmm );
  1970     if ( args->
just < 0.499 )
  1975     else if ( args->
just > 0.501 )
  1985     prev_font = set_font( dev,
  1986         (LONG) state.font_height,
  1987         (LONG) state.rotation,
  1992         state.font_family );
  1993     prev_color  = SetTextColor( dev->hdc, dev->color );
  1994     prev_bkmode = SetBkMode( dev->hdc, TRANSPARENT );
  2001         int    height = 0, width = 0;
  2006         len    = strlen( args->
string );
  2007         buffer = HeapAlloc( wingdi_heap, 0, ( len + 1 ) * 
sizeof ( 
char ) );
  2008         if ( buffer == NULL )
  2010             plexit( 
"wingdi: Unable to allocate character buffer\n" );
  2018         for ( i = j = 0; i < len + 1; i++ )
  2020             if ( args->
string[i] != esc && args->
string[i] != 
'\0' )
  2024                 buffer[j++] = args->
string[i];
  2026             else if ( i != len && args->
string[i + 1] == esc )
  2030                 buffer[j++] = args->
string[i];
  2044                     GetTextExtentPoint32( dev->hdc,
  2052                     width += segment_size.cx;
  2053                     if ( segment_size.cy > height )
  2054                         height = segment_size.cy;
  2060                     process_text_escape( dev, args,
  2068         if ( text_segments > 1 )
  2070             UINT save_text_align;
  2084                 rx -= (int) ( cos_rot * 0.5 * (
PLFLT) width );
  2085                 ry += (int) ( sin_rot * 0.5 * (
PLFLT) width );
  2088             save_text_align = SetTextAlign( dev->hdc, TA_LEFT | valign );
  2092             for ( i = j = 0; i < len + 1; i++ )
  2094                 if ( args->
string[i] != esc && args->
string[i] != 
'\0' )
  2098                     buffer[j++] = args->
string[i];
  2100                 else if ( i != len && args->
string[i + 1] == esc )
  2104                     buffer[j++] = args->
string[i];
  2117                         GetTextExtentPoint32( dev->hdc,
  2122                         sx = (int) ( ( 1.0 - cos_rot ) * (
PLFLT) state.soffset );
  2123                         sy = (int) ( ( 1.0 - sin_rot ) * (
PLFLT) state.soffset );
  2130                         rx += (int) ( cos_rot * (
PLFLT) segment_size.cx );
  2131                         ry -= (int) ( sin_rot * (
PLFLT) segment_size.cx );
  2136                         process_text_escape( dev, args,
  2142         HeapFree( wingdi_heap, 0, buffer );
  2149     if ( text_segments == 1 )
  2155         UINT save_text_align;
  2157         save_text_align = SetTextAlign( dev->hdc, halign | valign );
  2163         SetTextAlign( dev->hdc, save_text_align );
  2167     if ( prev_font != NULL )
  2168         SelectObject( dev->hdc, prev_font );
  2169     SetTextColor( dev->hdc, prev_color );
  2170     SetBkMode( dev->hdc, prev_bkmode );
  2179     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  2181     pldebug( 
"wingdi", 
"End of the page\n" );
  2183     if ( dev->type == DEV_WINDOW )
  2185         CopySCRtoBMP( pls );
  2187         EndPage( dev->hdc );
  2190     NormalCursor( dev );
  2193     dev->state = DEV_ACTIVE;
  2202     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  2203     pldebug( 
"wingdi", 
"Start of Page\n" );
  2206     dev->state = DEV_DRAWING;
  2209     update_status_bar( dev );
  2214     if ( dev->type == DEV_WINDOW )
  2220         SendMessage( dev->plot,
  2227         StartPage( dev->hdc );
  2240     struct wingdi_Dev *dev = NULL;
  2242     pldebug( 
"wingdi", 
"plD_tidy_wingdi\n" );
  2244     if ( pls->
dev != NULL )
  2246         dev = (
struct wingdi_Dev *) pls->
dev;
  2248         if ( dev->hdc != NULL )
  2249             ReleaseDC( dev->plot, dev->hdc );
  2251         if ( dev->bitmap != NULL )
  2252             DeleteObject( dev->bitmap );
  2254         if ( dev->plot != NULL )
  2255             DestroyWindow( dev->plot );
  2256         if ( dev->status_bar != NULL )
  2257             DestroyWindow( dev->status_bar );
  2258         if ( dev->frame != NULL )
  2259             DestroyWindow( dev->frame );
  2263         wingdi_module_cleanup();
  2276     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  2279     wait_for_user_input( pls );
  2291     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  2306     if ( dev->pen != NULL )
  2307         DeleteObject( dev->pen );
  2308     dev->pen = CreatePen( PS_SOLID, (
int) pls->
width, dev->color );
  2317 #ifndef PLESC_TELLME  2327     void *roomformore[6];
  2330 #define PLESC_TELLME    41  2336     struct wingdi_Dev *dev = (
struct wingdi_Dev *) pls->
dev;
  2345         plD_fill_polygon_wingdi( pls );
  2349         plD_clear_wingdi( pls,
  2355         plD_text_wingdi( pls, (
EscText *) ptr );
  2365         if ( *(
PLINT *) ( ptr ) == 0 )
  2366             SetROP2( dev->hdc, R2_COPYPEN );
  2368             SetROP2( dev->hdc, R2_XORPEN );
  2417         struct passmeup *pup = ptr;
  2419         pup->hwnd = &( dev->plot );
  2420         pup->hdc  = &( dev->hdc );
  2433 #endif                          // PLD_wingdidev int plParseDrvOpts(DrvOpt *acc_opt)
void plP_script_scale(PLBOOL ifupper, PLINT *level, PLFLT *old_scale, PLFLT *scale, PLFLT *old_offset, PLFLT *offset)
void plexit(PLCHAR_VECTOR errormsg)
#define PLESC_DOUBLEBUFFERING
void(* plD_tidy_fp)(struct PLStream_struct *)
void plGinInit(PLGraphicsIn *gin)
void(* plD_init_fp)(struct PLStream_struct *)
void(* plD_eop_fp)(struct PLStream_struct *)
void(* plD_wait_fp)(struct PLStream_struct *)
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
#define PLESC_END_RASTERIZE
static PLCHAR_VECTOR program
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
#define PLDLLIMPEXP_DRIVER
static PLStream * pls[PL_NSTREAMS]
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
void plRotationShear(PLFLT *xFormMatrix, PLFLT *rotation, PLFLT *shear, PLFLT *stride)
unsigned short unicode_array_len
void plRemakePlot(PLStream *pls)
#define PLESC_START_RASTERIZE
void(* plD_bop_fp)(struct PLStream_struct *)
PLDLLIMPEXP_DRIVER void plD_dispatch_init_wingdi(PLDispatchTable *pdt)
void plwarn(PLCHAR_VECTOR errormsg)
plD_polyline_fp pl_polyline
void(* plD_state_fp)(struct PLStream_struct *, PLINT)