Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

978 lines
30 KiB

/*************************** Module Header ********************************
* enablpdv.c
* Functions associated with EnablePDEV/RestartPDEV/CompletePDEV/
* DisablePDEV.
* EnablePDEV is called after EnableDriver, and is the call when
* the driver sets up any storage or other requirements, except
* any storage associated with the drawing surface. RestartPDEV is
* called when the device configuration is being changed in a
* major way, for example changing from Portraint to Landscape mode.
* DisablePDEV is called when the engine has finished with the
* physical device.
*
* 13:43 on Mon 19 Nov 1990 -by- Lindsay Harris [lindsayh]
*
* Copyright (C) 1990 - 1993 Microsoft Corporation
*
*************************************************************************/
#include <stddef.h>
#include <windows.h>
#include <winddi.h>
#include "pdev.h"
#include <string.h>
#include "fnenabl.h"
#include <libproto.h>
#include <winres.h>
#include "win30def.h"
#include "udmindrv.h"
#include "udpfm.h"
#include "uddevice.h"
#include "stretch.h"
#include "udrender.h"
#include <winspool.h>
#include "rasdd.h"
//sandram
#include "udresrc.h"
#include "udfnprot.h"
#include "oem.h"
BYTE cxHTPatSize[] = { 2,2,4,4,6,6,8,8,10,10,12,12,14,14,16,16 };
BYTE cyHTPatSize[] = { 2,2,4,4,6,6,8,8,10,10,12,12,14,14,16,16 };
#if DBG
DWORD gdwEnablPdevCount = 0;
DWORD gdwDisablPdevCount = 0;
extern HSEMAPHORE hsem ;
#endif
/*
* Set heap sizes. The minimum is the amount allocated at the start
* of operations, while the maximum is set to zero, meaning that the
* limit is set by the amount of memory the process can have.
*/
#define HEAP_MIN_SIZE ( 16 * 1024) /* Min bytes allocated for heap */
#define HEAP_MAX_SIZE (1024 * 1024) /* Max bytes allocated for heap */
/*
* Private local function prototypes.
*/
BOOL bGetDevInfo( PDEV *, DEVINFO *, GDIINFO *);
BOOL bInitPDEV( PDEV *, DEVMODEW *, PWSTR, ULONG, HSURF *, ULONG, ULONG *, ULONG, DEVINFO *,
HDEV, PWSTR, HANDLE );
void vLogFont( LOGFONT *, FONTMAP * );
/******************************Public*Routine******************************\
* vFreePdev
*
* free any memory allocated for this pdev
*
*
* History:
* 01-Mar-1995 -by- Eric Kutter [erick]
* Wrote it.
\**************************************************************************/
VOID vFreePdev(
PDEV *ppdev)
{
if (ppdev->pstrDataFile)
DRVFREE(ppdev->pstrDataFile);
if (ppdev->pstrModel)
DRVFREE(ppdev->pstrModel);
ASSERTRASDD(!(ppdev->pvRenderData),"RASDD!vFreePdev:pvRenderData should be NULL\n");
ASSERTRASDD(!(ppdev->pFileList),"RASDD!vFreePdev:ppdev->pFileList should be NULL\n");
#if NEED_TO_FREERES
if (ppdev->pNTRes)
DRVFREE( ppdev->pNTRes );
if (ppdev->pGPCData)
DRVFREE( ppdev->pGPCData );
#endif
if (ppdev->pUDPDev)
DRVFREE(ppdev->pUDPDev);
DRVFREE(ppdev);
}
/************************* Function Header *******************************
* DrvEnablePDEV
* Function called to let the driver create the data structures
* needed to support the device, and also to tell the engine
* about its capabilities. This is the stage where we find out
* exactly which device we are dealing with, and so we need to
* find out its capabilities.
*
* HISTORY:
* 17:03 on Thu 20 Aug 1992 -by- Lindsay Harris [lindsayh]
* Converted to UNICODE with wide structures.
*
* 28-May-1991 Tue 12:56:16 updated -by- Daniel Chou (danielc)
* clear the PDEV to all zeros after get it from heap
*
* 17:41 on Thu 14 Feb 1991 -by- Lindsay Harris [lindsayh]
* Updated to new DDI spec.
*
* 13:47 on Mon 19 Nov 1990 -by- Lindsay Harris [lindsayh]
* Created it.
*
*************************************************************************/
DHPDEV
DrvEnablePDEV( pdevmode, pwstrPrtName, cPatterns, phsurfPatterns,
cjGdiInfo, pulGdiInfo, cjDevInfo, pdevinfo,
hdev, pwstrDeviceName, hDriver )
DEVMODEW *pdevmode; /* Driver data */
PWSTR pwstrPrtName; /* Printer's name in CreateDC() */
ULONG cPatterns; /* Count of standard patterns */
HSURF *phsurfPatterns; /* Buffer for standard patterns */
ULONG cjGdiInfo; /* Size of buffer for GdiInfo */
ULONG *pulGdiInfo; /* Buffer for GDIINFO */
ULONG cjDevInfo; /* Number of bytes in devinfo */
DEVINFO *pdevinfo; /* Device info */
HDEV hdev; // HDEV, used for callbacks
PWSTR pwstrDeviceName; /* Device Name - "LaserJet II" */
HANDLE hDriver; /* Printer handle for spooler access */
{
/*
* The engine requires a new physical device from us. Thus,
* we need to allocate the storage and initialise it for the
* particular device.
* Function returns a handle to the pdev, which is returned to us
* in RestartPDEV and CompletePDEV, and also EnableSurface.
*/
PDEV *pPDev = NULL; /* Ditto */
#if DBG
EngAcquireSemaphore(hsem);
gdwEnablPdevCount++;
EngReleaseSemaphore(hsem);
//SetAllocCounters();
#endif
/*
* We need to get the full path of the driver to load the module from.
* We used to just use "rasdd.dll" but if there were multiple drivers
* lying around, one in the '0' directory and one in the '1' directory,
* it is undefined which driver you get so you can get the resources for
* the wrong driver (erick 4/6/94).
*/
if( (pPDev = (PDEV *)DRVALLOC( sizeof( PDEV ) )) )
{
/*
* make sure start with clean state
*/
ZeroMemory( pPDev, sizeof( PDEV ) );
pPDev->hheap = 0; /* For future reference */
pPDev->ulID = PDEV_ID; /* Just for checking! */
pPDev->hPrinter = hDriver;
/* Convert logical address to path name to info about this device. */
if( !(pPDev->pstrDataFile = WstrToHeap( pPDev->hheap,
EngGetPrinterDataFileName(hdev)
)) ||
!(pPDev->pstrModel = WstrToHeap( pPDev->hheap, pwstrDeviceName )) )
{
vFreePdev(pPDev);
pPDev = NULL;
}
else
{
pPDev->pstrPrtName = NULL;
// Get a handle to the driver DLL module from DDI.
if ( !(pPDev->hModDrv = EngLoadModule(EngGetDriverName(hdev))) )
{
RIP("Rasdd!DrvEnablePDEV:EngLoadModule on Rasdd Failed");
vFreePdev(pPDev);
pPDev = NULL;
#if DO_LATER
//Get a handle for loading minidrivers for callbacks.
if (!( pPDev->hImageMod = EngLoadImage(pPDev->pstrDataFile)) )
{
RIP("Rasdd!DrvEnablePDEV:EngLoadImage Failed\n");
vFreePdev(pPDev);
pPDev = NULL;
}
#endif
}
/*
* Now that we know where everything is located, we can determine
* our specific characteristics.This requires us to read the Windows
* mini-driver resources so that we can set our own capabilities.
*/
else if ( !bInitPDEV( pPDev, pdevmode, pwstrPrtName, cPatterns, phsurfPatterns,
cjGdiInfo, pulGdiInfo, cjDevInfo, pdevinfo, hdev, pwstrDeviceName,
hDriver ) )
{
/* Initialisation failed, so free the heap and return. */
RASDERRMSG("bInitPDEV");
vFreePdev(pPDev);
pPDev = NULL;
}
}
}
return (DHPDEV)pPDev;
}
/****************************** Function Header ****************************
* IsPaperSizeAndSourceSameAndOrientDifferent
* Checks the PaperSize of Old and new PDEV. It takes care of Orientation.
* Also checks if the orientation is different.
* RETURNS:
* TRUE - if PaperSize and Source are same
* FALSE - other wise.
*
* HISTORY:
* 15:54 on SAT 06 Jan 1995 -by- Ganesh Pandey [ganeshp]
* Initial version - probably not complete.
*
***************************************************************************/
BOOL
IsPaperSizeAndSourceSameAndOrientDifferent(
UD_PDEV *pUDPDevNew,
UD_PDEV *pUDPDevOld
)
{
POINT ptPhysNew,ptPhysOld; /* physical paper size */
if (pUDPDevNew->iOrient == pUDPDevOld->iOrient)
return FALSE;
//Get the Size for New PDEV
if ( pUDPDevNew->iOrient == DMORIENT_LANDSCAPE )
{
ptPhysNew.x = pUDPDevNew->pfPaper.ptPhys.y;
ptPhysNew.y = pUDPDevNew->pfPaper.ptPhys.x;
}
else
{
ptPhysNew.x = pUDPDevNew->pfPaper.ptPhys.x;
ptPhysNew.y = pUDPDevNew->pfPaper.ptPhys.y;
}
//Get the Size from Old PDEV.
if ( pUDPDevOld->iOrient == DMORIENT_LANDSCAPE )
{
ptPhysOld.x = pUDPDevOld->pfPaper.ptPhys.y;
ptPhysOld.y = pUDPDevOld->pfPaper.ptPhys.x;
}
else
{
ptPhysOld.x = pUDPDevOld->pfPaper.ptPhys.x;
ptPhysOld.y = pUDPDevOld->pfPaper.ptPhys.y;
}
return ( (ptPhysNew.x == ptPhysOld.x) &&
(ptPhysNew.y == ptPhysOld.y) &&
(pUDPDevNew->sPaperSource == pUDPDevOld->sPaperSource) );
}
/****************************** Function Header ****************************
* DrvResetPDEV
* Called when an application wishes to change the output style in the
* midst of a job. Typically this would be to change from portrait to
* landscape or vice versa. Any other sensible change is permitted.
*
* RETURNS:
* TRUE - device successfully reorganised
* FALSE - unable to change - e.g. change of device name.
*
* HISTORY:
* 15:54 on Fri 05 Jan 1995 -by- Ganesh Pandey [ganeshp]
* Initial version - probably not complete.
*
***************************************************************************/
BOOL
DrvResetPDEV
(
DHPDEV dhpdevOld, /* Original PDEV */
DHPDEV dhpdevNew /* New PDEV */
)
{
UD_PDEV *pUDPDevOld, *pUDPDevNew;
PDEV *pPDEVOld, *pPDEVNew;
BOOL bOK = FALSE;
pPDEVOld = (PDEV *)dhpdevOld;
pPDEVNew = (PDEV *)dhpdevNew;
pUDPDevNew = (UD_PDEV *)(pPDEVNew->pUDPDev);
pUDPDevOld = (UD_PDEV *)(pPDEVOld->pUDPDev) ;
/* Validate the PDEVs */
if( (pPDEVOld->ulID != PDEV_ID) || (pPDEVNew->ulID != PDEV_ID) )
{
RIP( "INCORRECT PDEV ID in DrvResetPDEV (RasDD)" );
return(bOK);
}
/* Notify OEM
*/
bOK = bOEMResetPDEV(pPDEVOld, pPDEVNew);
/*
* Set this flag only when initialization is not needed, because it will
* eject the page. Check if DrvStartDoc was called for the old PDEVICE
* because DrvRestPDev can be called between documents also. We are only
* interested in the case where the document has started printing.
*
*/
if( (pUDPDevOld->fMode & PF_DOCSTARTED) &&
(pUDPDevNew->fMDGeneral & MD_DUPLEX) &&
(pUDPDevNew->sDuplex != DMDUP_SIMPLEX) &&
(pUDPDevNew->sDuplex == pUDPDevOld->sDuplex) &&
(IsPaperSizeAndSourceSameAndOrientDifferent(pUDPDevNew,pUDPDevOld)) )
{
pUDPDevNew->fMode |= PF_RESET_NOINIT_PG;
}
return(bOK);
}
/****************************** Function Header ****************************
* bInitPDEV
* Function to perform the PDEV initialisation. This is common to
* DrvEnablePDEV and DrvRestartPDEV. These individual functions
* do whatever is required before calling in here.
*
* RETURNS:
* TRUE - successful initialisation
* FALSE - unable to do the job (error code logged)
*
* HISTORY:
* 29-May-1991 Wed 21:39:40 updated -by- Daniel Chou (danielc)
* Calling EnableHalftone()
*
* 15:46 on Fri 01 Mar 1991 -by- Lindsay Harris [lindsayh]
* Split out from DrvEnablPDEV
*
* 27-Jan-1993 Wed 07:34:04 updated -by- Daniel Chou (danielc)
* clean up, have engine do the work
*
****************************************************************************/
BOOL
bInitPDEV( pPDev, pdevmode, pwstrPrtName, cPatterns, phsurfPatterns, cjGdiInfo, pulGdiInfo,
cjDevInfo, pdevinfo, hdev, pwstrDeviceName, hdriver )
PDEV *pPDev; /* The device of interest */
PWSTR pwstrPrtName; /* Printer name */
DEVMODEW *pdevmode; /* User's devmode */
ULONG cPatterns; /* Count for standard patterns */
HSURF *phsurfPatterns; /* Handles to standard patterns */
ULONG cjGdiInfo; /* Bytes in the devcaps following */
ULONG *pulGdiInfo; /* Place for the devcaps data */
ULONG cjDevInfo; /* Bytes in the device info following */
DEVINFO *pdevinfo; /* Place for the DEVINFO data */
HDEV hdev; /* HDEV, for callbacks */
PWSTR pwstrDeviceName; /* Model name */
HANDLE hdriver; /* Printer handle for spooler access */
{
/*
* Printer characterisation is determined from the devmode and
* minidriver resources. First step is to obtain the minidriver
* data.
*/
GDIINFO GdiInfo; /* UniDrv code fills it in for us */
DEVINFO DevInfo; /* Device caps */
OEMENABLEPDEVPARAM OEMParam = {0};
/*
* Initialise the LOCAL structures to 0 before passing off to the
* functions that (selectively) fill them in.
*/
ZeroMemory( &GdiInfo, sizeof( GdiInfo ) );
ZeroMemory( &DevInfo, sizeof( DevInfo ) );
//
// We first NULL out all HSURF which engine asked for, this will cause
// engine to automatically generate best standard patterns for this
// particular device
//
ZeroMemory( phsurfPatterns, sizeof(HSURF) * cPatterns);
/* Fill out what we know of OEMENABLEPDEVPARAM.
*/
OEMParam.cbSize = sizeof(OEMENABLEPDEVPARAM);
OEMParam.pdm = pdevmode;
OEMParam.pwszLogAddress = pwstrPrtName;
OEMParam.cPat = cPatterns;
OEMParam.phsurfPatterns = phsurfPatterns;
OEMParam.cjCaps = cjGdiInfo;
OEMParam.pdevcaps = pulGdiInfo;
OEMParam.cjDevInfo = cjDevInfo;
OEMParam.pdi = pdevinfo;
OEMParam.hdev = hdev;
OEMParam.pwszDeviceName = pwstrDeviceName;
OEMParam.hDriver = hdriver;
if( !udInit( pPDev, &GdiInfo, pdevmode, &OEMParam ) )
return FALSE;
/*
* Initialise the DEVINFO structure and also initialise the pattern
* information requested by the engine. First step is to try
* initialising the halftone info & dll.
*/
GdiInfo.flHTFlags = HT_FLAG_HAS_BLACK_DYE;
if (!bGetDevInfo( pPDev, &DevInfo, &GdiInfo ))
{
return(FALSE);
}
DevInfo.cxDither = cxHTPatSize[GdiInfo.ulHTPatternSize];
DevInfo.cyDither = cyHTPatSize[GdiInfo.ulHTPatternSize];
/*
* Everything completed OK, so we can overwrite the data areas
* passed in to us.
*/
cjGdiInfo = min( cjGdiInfo, sizeof( GDIINFO ) );
CopyMemory( pulGdiInfo, &GdiInfo, cjGdiInfo );
cjDevInfo = min( cjDevInfo, sizeof( DEVINFO ) );
CopyMemory( pdevinfo, &DevInfo, cjDevInfo );
return TRUE;
}
/***************************** Function Header **************************
* DrvCompletePDEV
* Called when the engine has completed installation of the physical
* device. Basically it provides the connection between the
* engine's hdev and ours. Some functions require us to pass in
* the engines's hdev, so we save it now in our pdev so that we
* can get to it later.
*
* HISTORY:
* 17:41 on Thu 14 Feb 1991 -by- Lindsay Harris [lindsayh]
* Updated to new DDI spec.
*
* 16:46 on Mon 19 Nov 1990 -by- Lindsay Harris [lindsayh]
* Created it.
*
************************************************************************/
void
DrvCompletePDEV( dhpdev, hdev )
DHPDEV dhpdev; /* Returned from dhpdevCreatePDEV */
HDEV hdev; /* Engine's corresponding handle */
{
/*
* Simply record the value in the PDEV we have allocated.
* ALWAYS returns TRUE.
*/
((PDEV *)dhpdev)->hdev = hdev;
return;
}
/***************************** Function Header **************************
* DrvDisablePDEV
* Called when the engine has finished with this PDEV. Basically
* we throw away all connections etc. then free the heap.
*
* HISTORY:
* 10:04 on Thu 23 May 1991 -by- Lindsay Harris [lindsayh]
* Freed halftone module, if used.
*
* 17:42 on Thu 14 Feb 1991 -by- Lindsay Harris [lindsayh]
* Updated to new DDI spec
*
* 16:22 on Mon 19 Nov 1990 -by- Lindsay Harris [lindsayh]
* Created it.
*
* 29-May-1991 Wed 21:39:40 updated -by- Daniel Chou (danielc)
* Calling DiableHalftone()
*
************************************************************************/
VOID
DrvDisablePDEV( dhpdev )
DHPDEV dhpdev;
{
/*
* Undo all that has been done with the PDEV. Basically this means
* freeing the memory we consumed.
*/
/* Notify OEM.
*/
vOEMDisablePDEV((PDEV*) dhpdev);
/*
* Free any font memory that may have been allocated.
*/
#define pPDEV ((PDEV *)dhpdev)
#if DBG
EngAcquireSemaphore(hsem);
gdwDisablPdevCount++;
EngReleaseSemaphore(hsem);
#endif
vFontFreeMem( pPDEV );
/*
* Free the resource data - NT or WIN 3.1
*/
if( pPDEV->pvWinResData )
{
WinResClose( pPDEV->pvWinResData );
/* Free the Resource data */
if (pPDEV->pvWinResData)
DRVFREE(pPDEV->pvWinResData);
pPDEV->pvWinResData = 0;
}
/*
* And any palette data.
*/
if( pPDEV->hpal )
EngDeletePalette( pPDEV->hpal );
/* Delete the Pallete Data */
if( pPDEV->pPalData )
DRVFREE(pPDEV->pPalData);
/* Unload the Image if loaded for callbacks */
if( pPDEV->hImageMod )
EngUnloadImage( pPDEV->hImageMod );
/* Unload Rasdd Module Handle, loaded for rasdd resources */
if (pPDEV->hModDrv)
EngFreeModule(pPDEV->hModDrv);
//derryd Free The mini PDEV
if( ((UD_PDEV*)(pPDEV->pUDPDev))->pMDev )
{
DRVFREE(((UD_PDEV*)(pPDEV->pUDPDev))->pMDev);
((UD_PDEV*)(pPDEV->pUDPDev))->pMDev = NULL;
}
vFreePdev(pPDEV);
return;
}
/************************** FUNCTION HEADER **********************************
* bGetDevInfo
* Set up the device caps for this particular printer. Some fields
* require calculations based on device resolution, etc.
*
* RETURNS:
* True for success, False for error.
*
* HISTORY:
* 18:16 on Wed 03 Jul 1991 -by- Lindsay Harris [lindsayh]
* Returns number of colours in palette
*
* 29-May-1991 Wed 21:40:02 updated -by- Daniel Chou (danielc)
* Add in halftone codes and re-order the color table/palette
*
* 14:54 on Thu 21 Feb 1991 -by- Lindsay Harris [lindsayh]
* Filled it in, now that engine looks at data.
*
* 11-Oct-1991 Fri 19:08:28 updated -by- Daniel Chou (danielc)
* Addin the HTDataFlags so that we remember if this device is monochrome
* or not, previously the color output (DitherBrush) was always monochrome
* even if output device is color, which cause strong blue appear in the
* color output for the grey color test
*
* 27-Jan-1993 Wed 07:35:37 updated -by- Daniel Chou (danielc)
* add in pGDIInfo parameter so we can setup more halftone parameters
* in GDIINFO to have engine work for us
*
****************************************************************************/
BOOL
bGetDevInfo( pPDev, pdevinfo, pGDIInfo )
PDEV *pPDev;
DEVINFO *pdevinfo; /* Where to put the data */
GDIINFO *pGDIInfo;
{
/*
* For now, we simply set it all to zero. This means we have no
* capabilities, but this is true for now. Later we may be able
* to include a default font.
*/
PAL_DATA *pPD;
UD_PDEV *ptUDPDev = pPDev->pUDPDev;
/* !!!Lindsayh: Still uses old format data !!! WILL NEED FIXING LATER */
#define pUDPDev ((UD_PDEV *)pPDev->pUDPDev)
/*
* We may need to change this graphic capabilities as we go along.
*/
pdevinfo->flGraphicsCaps = 0; /* Can't do a damn thing */
if( !(pPD = (PAL_DATA *)DRVALLOC( sizeof( PAL_DATA ) )) )
{
return(FALSE);
}
pPDev->pPalData = pPD; /* For all the others! */
if( pdevinfo->cFonts = pUDPDev->cFonts )
{
/* Device fonts are available, so set the default font data */
if( pUDPDev->pFMDefault )
vLogFont( &pdevinfo->lfDefaultFont, pUDPDev->pFMDefault );
}
ZeroMemory( &pdevinfo->lfAnsiVarFont, sizeof( LOGFONT ) );
ZeroMemory( &pdevinfo->lfAnsiFixFont, sizeof( LOGFONT ) );
/*
* We don't process DrvDitherColor (perhaps later?), so set the
* size of the Dither Brush to 0 to indicate this to the engine.
* THIS IS IN THE SPEC FOR DrvDitherBrush() function. HOWEVER,
* if halftoning is available, then we can do it!
*/
pdevinfo->flGraphicsCaps |= (GCAPS_ARBRUSHOPAQUE | GCAPS_HALFTONE | GCAPS_MONO_DITHER | GCAPS_COLOR_DITHER);
if( pUDPDev->fMode & PF_NOEMFSPOOL )
pdevinfo->flGraphicsCaps |= GCAPS_DONTJOURNAL;
if( pUDPDev->fMode & PF_SEIKO )
{
/* !!! HACK for Seiko printer */
long lRet;
int _iI;
PALETTEENTRY pe[ 256 ]; /* 8 bits per pel - all the way */
lRet = HT_Get8BPPFormatPalette(pe,
(USHORT)pGDIInfo->ciDevice.RedGamma,
(USHORT)pGDIInfo->ciDevice.GreenGamma,
(USHORT)pGDIInfo->ciDevice.BlueGamma );
if( lRet < 1 )
{
#if DBG
DbgPrint( "Rasdd!GetPalette8BPP returns %ld\n", lRet );
#endif
return(FALSE);
}
/*
* Convert the HT derived palette to the engine's desired format.
*/
for( _iI = 0; _iI < lRet; _iI++ )
{
pPD->ulPalCol[ _iI ] = RGB( pe[ _iI ].peRed,
pe[ _iI ].peGreen,
pe[ _iI ].peBlue );
}
pPD->iWhiteIndex = lRet;
pPD->cPal = lRet;
pdevinfo->iDitherFormat = BMF_8BPP;
pGDIInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
pGDIInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
}
//sandram - added another else for Color LaserJet
else if (pUDPDev->fMode & PF_8BPP)
{
long lRet;
lRet = lSetup8BitPalette (pUDPDev, pPD, pdevinfo, pGDIInfo);
if( lRet < 1 )
{
#if DBG
DbgPrint( "Rasdd!GetPalette8BPP returns %ld\n", lRet );
#endif
return(FALSE);
}
}
else if (pUDPDev->fMode & PF_24BPP)
{
long lRet;
lRet = lSetup24BitPalette (pPD, pdevinfo, pGDIInfo);
if( lRet < 1 )
{
#if DBG
DbgPrint( "Rasdd!GetPalette8BPP returns %ld\n", lRet );
#endif
return(FALSE);
}
}
else
{
if( pUDPDev->Resolution.fDump & RES_DM_COLOR )
{
/*
* We appear to GDI as an RGB surface, regardless of what
* the printer is. CMY(K) printers have their pallete
* reversed at rendering time. This is required for Win 3.1
* compatability and many things assume an RGB palette, and
* break if this is not the case.
*
* DC_PRIMARY_RGB
* ------------------------------------------
* Index 0 = Black
* Index 1 = Red
* Index 2 = Green
* Index 3 = Yellow
* Index 4 = Blue
* Index 5 = Magenta
* Index 6 = Cyan
* Index 7 = White
*--------------------------------------------
* Bit 0 = Red
* Bit 1 = Green
* Bit 2 = Blue
*
* If a separate black dye is available, this can be arranged
* to fall out at transpose time - we have a slightly different
* transpose table to do the work.
*/
/*
* Many apps and the engine presume an RGB colour model, so
* we pretend to be one! We invert the bits at render time.
*/
pPD->iWhiteIndex = 7;
/*
* Set the palette colours. Remember we are only RGB format.
* NOTE that gdisrv requires us to fill in all 16 entries,
* even though we have only 8. So the second 8 are a duplicate
* of the first 8.
*/
pPD->ulPalCol[ 0 ] = pPD->ulPalCol[ 8 ] = RGB( 0x00, 0x00, 0x00 );
pPD->ulPalCol[ 1 ] = pPD->ulPalCol[ 9 ] = RGB( 0xff, 0x00, 0x00 );
pPD->ulPalCol[ 2 ] = pPD->ulPalCol[ 10 ] = RGB( 0x00, 0xff, 0x00 );
pPD->ulPalCol[ 3 ] = pPD->ulPalCol[ 11 ] = RGB( 0xff, 0xff, 0x00 );
pPD->ulPalCol[ 4 ] = pPD->ulPalCol[ 12 ] = RGB( 0x00, 0x00, 0xff );
pPD->ulPalCol[ 5 ] = pPD->ulPalCol[ 13 ] = RGB( 0xff, 0x00, 0xff );
pPD->ulPalCol[ 6 ] = pPD->ulPalCol[ 14 ] = RGB( 0x00, 0xff, 0xff );
pPD->ulPalCol[ 7 ] = pPD->ulPalCol[ 15 ] = RGB( 0xff, 0xff, 0xff );
pPD->cPal = 16;
pdevinfo->iDitherFormat = BMF_4BPP;
pdevinfo->flGraphicsCaps |= GCAPS_FORCEDITHER;
pGDIInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
pGDIInfo->ulHTOutputFormat = HT_FORMAT_4BPP;
/*
* !ganeshp:Temp Fix for fixing the mapping light gray color to
* white on color Printers.This will be removed once we have
* text dithering capability in GDI and support for getting
* back the original color. Map a Off white Color to black on
* color printers.
*/
pPD->ulPalCol[ 8 ] = RGB( 0xf0, 0xf0, 0xf0 );
}
else
{
/*
* Monochrome printer, so there are only 2 colours, black
* and white. It would be nice if the bitmap was set with
* black as 1 and white as 0. HOWEVER, there are presumptions
* all over the place that 0 is black. SO, we set them to
* the preferred way, then invert before rendering.
*/
pPD->cPal = 2;
pPD->ulPalCol[ 0 ] = RGB(0x00, 0x00, 0x00);
pPD->ulPalCol[ 1 ] = RGB(0xff, 0xff, 0xff);
pPD->iWhiteIndex = 1;
pdevinfo->iDitherFormat = BMF_1BPP; /* Monochrome format */
pGDIInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
pGDIInfo->ulHTOutputFormat = HT_FORMAT_1BPP;
}
}
if (pUDPDev->sBitsPixel == 24 && pUDPDev->sDevPlanes == 1)
pPDev->hpal = pdevinfo->hpalDefault = EngCreatePalette( PAL_RGB,
0, 0, 0, 0, 0 );
else
pPDev->hpal = pdevinfo->hpalDefault = EngCreatePalette( PAL_INDEXED,
pPD->cPal, pPD->ulPalCol,
0, 0, 0 );
if (pPDev->hpal == (HPALETTE) NULL)
{
return(FALSE);
}
pGDIInfo->ulNumPalReg = pPD->cPal;
return(TRUE);
#undef pUDPDev
}
/****************************** Function Header *****************************
* vLogFont
* Turn an IFIMETRICS structure into a LOGFONT structure, for whatever
* reason this is needed.
*
* RETURNS:
* Nothing, as this function cannot fail!
*
* HISTORY:
* 16:46 on Sat 20 Mar 1993 -by- Lindsay Harris [lindsayh]
* Formalise it, handle scalable fonts.
*
* Initial version was written in the early days.
*
****************************************************************************/
void
vLogFont( pLF, pFM )
LOGFONT *pLF; /* Output is a LOGFONT */
FONTMAP *pFM; /* Input is a FONTMAP */
{
/*
* Convert from IFIMETRICS to LOGFONT type structure.
*/
int iLen; /* Loop variable */
IFIMETRICS *pIFI;
WCHAR *pwch; /* Address of face name */
pIFI = pFM->pIFIMet; /* The BIG metrics */
pLF->lfHeight = pIFI->fwdWinAscender + pIFI->fwdWinDescender;
pLF->lfWidth = pIFI->fwdAveCharWidth;
/*
* Note that this may be a scalable font, in which case we pick a
* reasonable number!
*/
if( pIFI->flInfo & (FM_INFO_ISOTROPIC_SCALING_ONLY|FM_INFO_ANISOTROPIC_SCALING_ONLY|FM_INFO_ARB_XFORMS))
{
/*
* Invent an arbitrary size. We choose an approximately 10 point
* font. The height is achieved easily, as we simply set the
* height based on the device resolution! For the width, adjust
* it using the same factor as we used on the height. This
* assumes that the resolution is the same in both directions,
* but this is reasonable given laser printers are the most
* common with scalable fonts.
*/
pLF->lfHeight = pFM->wYRes / 7; /* This is about 10 points */
pLF->lfWidth = (2 * pLF->lfHeight * pFM->wXRes) / (3 * pFM->wYRes);
}
pLF->lfEscapement = 0;
pLF->lfOrientation = 0;
pLF->lfWeight = pIFI->usWinWeight;
pLF->lfItalic = (BYTE)((pIFI->fsSelection & FM_SEL_ITALIC) ? 1 : 0);
pLF->lfUnderline = (BYTE)((pIFI->fsSelection & FM_SEL_UNDERSCORE) ? 1 : 0);
pLF->lfStrikeOut = (BYTE)((pIFI->fsSelection & FM_SEL_STRIKEOUT) ? 1 : 0);
pLF->lfCharSet = pIFI->jWinCharSet;
pLF->lfOutPrecision = OUT_DEFAULT_PRECIS;
pLF->lfClipPrecision = CLIP_DEFAULT_PRECIS;
pLF->lfQuality = DEFAULT_QUALITY;
pLF->lfPitchAndFamily = pIFI->jWinPitchAndFamily;
/*
* Copy the face name, after figuring out it's address!
*/
pwch = (WCHAR *)((BYTE *)pIFI + pIFI->dpwszFaceName);
iLen = min( wcslen( pwch ), LF_FACESIZE - 1 );
wcsncpy( pLF->lfFaceName, pwch, iLen );
pLF->lfFaceName[ iLen ] = (WCHAR)0;
return;
}