BOOL DrvEndDoc( SURFOBJ *pso, FLONG Flags ) /*++ Routine Description: This function end the control information on the device for the document Arguments: pso - Pointer to the SURFOBJ for the device Flags - if ED_ABORTDOC bit is set then the document has been aborted Return Value: BOOLLEAN to specified if function sucessful Author: 30-Nov-1993 Tue 21:16:48 created -by- Daniel Chou (danielc) Revision History: --*/ { PPDEV pPDev; if (!(pPDev = SURFOBJ_GETPDEV(pso))) { PLOTERR(("DrvEndDoc: invalid pPDev")); return(FALSE); } // // TODO we should review if we should do anything here... // PLOTDBG(DBG_ENDDOC,("DrvEndDoc called with Flags = %08lx", Flags)); return(TRUE); }
_Use_decl_annotations_ BOOL WINAPI DrvStrokePath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, BRUSHOBJ *pbo, PPOINTL pptlBrushOrg, LINEATTRS *plineattrs, MIX Mix ) /*++ Routine Description: The driver's function for the StrokePath Arguments: same as EngStrokePath Return Value: TRUE if sucessful FALSE if failed Author: 8/18/92 -- t-alip Rewrote it. 30-Nov-1993 Tue 22:21:51 updated updated by DC 04-Aug-1994 Thu 20:00:23 updated bug# 22348 Revision History: 31-Jan-1994 Tue 22:21:51 updated Fixed dopolygon to pass in ROP4 not just MIX --*/ { PPDEV pPDev; BOOL bRetVal; UNREFERENCED_PARAMETER(pxo); PLOTDBG(DBG_STROKEPATH, ("DrvStrokePath: Mix = %x", Mix)); if (!(pPDev = SURFOBJ_GETPDEV(pso))) { PLOTERR(("DrvStrokePath: Invalid pPDev")); return(FALSE); } if (!(bRetVal = DoPolygon(pPDev, NULL, pco, ppo, pptlBrushOrg, NULL, pbo, MixToRop4(Mix), plineattrs, FPOLY_STROKE) )) { // // Since DoPolygon failed, it can only be because we had both a complex // clip and a pathobj, so the thing to here is do the stroke via another // method using some of the engine helpers. // // We will also failed when STYLE LINE + DC_RECT when raster plotter is // used // bRetVal = DoStrokePathByEnumingClipLines( pPDev, pso, pco, ppo, pptlBrushOrg, pbo, MixToRop4(Mix), plineattrs); } return(bRetVal); }
BOOL DevQueryPrintEx( PDEVQUERYPRINT_INFO pDQPInfo ) /*++ Routine Description: This routine determines whether or not the driver can print the job described by pDevMode on the printer described by hPrinter Arguments: pDQPInfo - Pointer to DEVQUERYPRINT_INFO data structure typedef struct _DEVQUERYPRINT_INFO { WORD cbSize; // size of this structure in bytes WORD Level; // Level of this info, 1 for this version HANDLE hPrinter; // handle to the printer for the query DEVMODE *pDevMode; // pointer to the DEVMODE for this job. LPTSTR pszErrorStr; // pointer to the error string buffer. WORD cchErrorStr; // count characters of pszErrorStr passed. WORD cchNeeded; // count characters of pszErrorStr needed. } DEVQUERYPRINT_INFO, *PDEVQUERYPRINT_INFO; cbSize - size of this structure Level - This must be one (1) for this version of structure hPrinter - Identifies the printer on which the job is to be printed. pDevMode - Points to the DEVMODE structure that describes the print job that is to be determined as printable or non-printable by hPrinter. The driver should always validate the DEVMODE structure whenever it is passed in. pszErrorStr - This is the pointer to a null terminated unicode string which to stored the reason for non-printable job. If the job is printable then it return TRUE. If the job is non-printable then it return FALSE, and a null terminated unicode string pointed by the pszErrorStr for the reason by this job is not printable. The size of this buffer in characters is specified by the cchErrorStr. cchErrorStr - Specified the size of pszErrorStr in characters (includs null terminator) when calling this function. If an error string is returned due to the non-printable job (returned FALSE), the driver will set ccchNeeded to the total characters (includes null terminator) required for the pszErrorStr, in this case the driver must always truncate the error string to fit into the pwErrorStr (only if it is not NULL) passed up to the cchErrorStr characters passed. cchNeeded - When driver returned FALSE, it specified total characters required for the pszErrorStr. If cchNeeded returned from the driver is larger then the cchErrorStr then it indicate the passed pszErrorStr is too small to hold the full error string, in this case the driver must always truncate the error string to fit into the pszErrorStr passed up to the cchErrorStr size. Return Value: BOOLEAN - TRUE - The job is printable and should not be hold. FALSE - The job is not printable and cchNeeded in the DEVQUERYPRINT_INFO data structure specified total characters required for the pszErrorStr. If returned cchNeeded is greater then cchErrorStr passed then it indicated that pszErrorStr is too small for storing the error string, in this case the driver must always truncate the error string to fit into the pszErrorStr passed, up to the cchErrorStr characters. *Note* The driver should have some predefined generic resource error strings for some possible known errors. such as memroy allocation error, data file not found, invalid devmode,... for returning non devmode related errors. The caller can pre-allocated larger buffer (such as 256 wchars) for storing the error string rather than calling this function twice. Author: 07-Feb-1996 Wed 20:37:31 created -by- Daniel Chou (danielc) Revision History: --*/ { PPRINTERINFO pPI = NULL; LONG ErrorResID = 0; static WCHAR wFormat1[] = L"<%s> %!"; // // if it passed a NULL DEVMODE then we just honor it to said can print // pDQPInfo->cchNeeded = 0; ErrorResID = IDS_FORM_NOT_AVAI; if (!pDQPInfo->pDevMode) { PLOTWARN(("DevQueryPrint: No DEVMODE passed, CANNOT PRINT")); ErrorResID = IDS_INVALID_DATA; } else if (!(pPI = MapPrinter(pDQPInfo->hPrinter, (PPLOTDEVMODE)pDQPInfo->pDevMode, (LPDWORD)&ErrorResID, MPF_DEVICEDATA))) { // // The MapPrinter will allocate memory, set default devmode, reading // and validating the GPC then update from current pritner registry, // PLOTRIP(("DevQueryPrint: MapPrinter() failed")); } else if (pPI->dmErrBits & (USER_PAPER | DM_FORMNAME)) { // // We encounter some errors, and the form has been set to default // PLOTWARN(("DevQueryPrint: CAN'T PRINT, dmErrBits=%08lx (PAPER/FORM)", pPI->dmErrBits)); } else if ((pPI->PlotDM.dm.dmFields & DM_FORMNAME) && (wcscmp(pPI->CurPaper.Name, pPI->PlotDM.dm.dmFormName) == 0)) { // // We can print this form now // ErrorResID = 0; PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: Match FormName=%s", pPI->PlotDM.dm.dmFormName)); } else if ((!pPI->CurPaper.Size.cy) || (((pPI->PlotDM.dm.dmFields & USER_PAPER) == USER_PAPER) && (pPI->PlotDM.dm.dmPaperSize == DMPAPER_USER)) || (pPI->PPData.Flags & PPF_SMALLER_FORM)) { LONG lTmp; SIZEL szl; BOOL VarLenPaper; // // 1. If we have ROLL PAPER Installed OR // 2. User Defined Paper Size // 3. User said OK to print smaller form then installed one // // THEN we want to see if it can fit into the device installed form // szl.cx = DMTOSPL(pPI->PlotDM.dm.dmPaperWidth); szl.cy = DMTOSPL(pPI->PlotDM.dm.dmPaperLength); if (VarLenPaper = (BOOL)!pPI->CurPaper.Size.cy) { pPI->CurPaper.Size.cy = pPI->pPlotGPC->DeviceSize.cy; } PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: CurPaper=%ldx%ld, Req=%ldx%ld, VarLen=%ld", pPI->CurPaper.Size.cx, pPI->CurPaper.Size.cy, szl.cx, szl.cy, VarLenPaper)); // // One of Following conditions met in that sequence then we can print // the form on loaded paper // // 1. Same size (PORTRAIT or LANDSCAPE) // 2. Larger Size (PORTRAIT or LANDSCAPE) AND // Not a variable length paper AND // PPF_SAMLLER_FORM flag set // if ((pPI->CurPaper.Size.cx < szl.cx) || (pPI->CurPaper.Size.cy < szl.cy)) { // // Swap this so we can do one easier comparsion later // SWAP(szl.cx, szl.cy, lTmp); } if ((pPI->CurPaper.Size.cx >= szl.cx) && (pPI->CurPaper.Size.cy >= szl.cy)) { if ((!VarLenPaper) && (!(pPI->PPData.Flags & PPF_SMALLER_FORM)) && ((pPI->CurPaper.Size.cx > szl.cx) || (pPI->CurPaper.Size.cy > szl.cy))) { PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: CAN'T PRINT: user DO NOT want print on larger paper")); } else { PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: Paper Size FITS in DEVICE, %ld x %ld", szl.cx, szl.cy)); ErrorResID = 0; } } else { DQPsprintf((HINSTANCE)hPlotUIModule, pDQPInfo->pszErrorStr, pDQPInfo->cchErrorStr, &(pDQPInfo->cchNeeded), wFormat1, pPI->PlotDM.dm.dmFormName, IDS_FORM_TOO_BIG); PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: CAN'T PRINT: Form Size too small")); } } PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: %s PRINT %s", (ErrorResID) ? "CAN'T" : "OK to", pPI->PlotDM.dm.dmFormName)); if ((!pDQPInfo->cchNeeded) && (ErrorResID)) { switch (ErrorResID) { case IDS_FORM_NOT_AVAI: DQPsprintf((HINSTANCE)hPlotUIModule, pDQPInfo->pszErrorStr, pDQPInfo->cchErrorStr, &(pDQPInfo->cchNeeded), wFormat1, pPI->PlotDM.dm.dmFormName, IDS_FORM_NOT_AVAI); break; default: DQPsprintf((HINSTANCE)hPlotUIModule, pDQPInfo->pszErrorStr, pDQPInfo->cchErrorStr, &(pDQPInfo->cchNeeded), L"%!", ErrorResID); break; } } // // Unget the printer GPC mapping if we got one // if (pPI) { UnMapPrinter(pPI); } return((!ErrorResID) && (!pDQPInfo->cchNeeded)); }
BOOL DoSpecialRop3( SURFOBJ *psoDst, CLIPOBJ *pco, PRECTL prclDst, DWORD Rop3 ) /*++ Routine Description: This function does a white or black fil Arguments: psoDst - The device surface must be DEVICE pco - Clipping object prclDst - RECTL area to be rop'ed Rop3 - a special Rop3, 0x00, 0xFF, 0x55, 0xAA Return Value: BOOLEAN Author: 15-Jan-1994 Sat 07:38:55 created Revision History: --*/ { BRUSHOBJ bo; DEVBRUSH DevBrush; PLOTASSERT(1, "DoSpecialRop3: Passed psoDst (%08lx) != STYPE_DEVICE", psoDst->iType == STYPE_DEVICE, psoDst); PLOTDBG(DBG_SPECIALROP, ("DoSpecialROP[%04lx] (%ld, %ld)-(%ld, %ld)=%ld x %ld", Rop3, prclDst->left, prclDst->top, prclDst->right, prclDst->bottom, prclDst->right - prclDst->left, prclDst->bottom - prclDst->top)); bo.iSolidColor = (DWORD)((Rop3) ? 0x000000000 : 0x00FFFFFF); bo.pvRbrush = (LPVOID)&DevBrush; ZeroMemory(&DevBrush, sizeof(DevBrush)); if (!DoFill(psoDst, // psoDst NULL, // psoSrc pco, // pco NULL, // pxlo prclDst, // prclDst NULL, // prclSrc &bo, // pbo (PPOINTL)&ptlZeroOrigin, // pptlBrushOrg Rop3 | (Rop3 << 8))) { // Rop4 PLOTERR(("DoSpecialRop3: Rop3=%08lx Failed!!!", Rop3)); return(FALSE); } return(TRUE); }
BOOL DoRop3( PPDEV pPDev, SURFOBJ *psoDst, SURFOBJ *psoSrc, SURFOBJ *psoPat, SURFOBJ *psoTmp, CLIPOBJ *pco, XLATEOBJ *pxlo, PRECTL prclDst, PRECTL prclSrc, PRECTL prclPat, PPOINTL pptlPatOrg, BRUSHOBJ *pbo, DWORD Rop3 ) /*++ Routine Description: This function performs ROP3 operations (one at a time) Arguments: pPDev - Pointer to the PDEV psoDst - pointer to the destination surface object psoSrc - pointer to the source surface object psoPat - Pointer to the pattern surface object psoTmp - pointer to the temp buffer surface object pco - clip object prclDst - pointer to the destination rectangle prclSrc - pointer to the source rectangle prclPat - pointer to the pattern rectangle pptlPatOrg - Pointer to the brush origin, if this is NULL then its assumed the pattern's prclPat does not have to be aligned on the destination pbo - a Brush object if we need to call DoFill() Rop3 - a ROP3 to be performed Return Value: BOOL Author: 20-Jan-1994 Thu 02:36:00 created 27-Jan-1994 Thu 23:46:28 updated Re-write to take other parameter, also move the cloning surface objects to the caller (ie. DrvBitBlt()) Revision History: --*/ { RECTL rclTmp; DWORD SDMix; DWORD Mix2; BYTE Flags; UINT Count; BOOL InvertMix2; BOOL Ok; PLOTDBG(DBG_ROP3, ("DoRop3: Rop3=%08lx", Rop3)); switch (Rop3 &= 0xFF) { case 0x00: // 0 case 0xFF: // 1 case 0x55: // ~D DoSpecialRop3(psoDst, pco, prclDst, Rop3); case 0xAA: // D // // This is NOP // return(TRUE); } // // Invert Rop3 if we are out of the data range (128-255) and then invert // the final result (by inverting last Mix2 Rop2 code (0-15), all Rop3/Rop2 // codes are symmetric. // if (Rop3 >= 0x80) { InvertMix2 = TRUE; SDMix = (DWORD)Rop3ToSDMix[Rop3 ^ 0xFF]; PLOTDBG(DBG_ROP3, ("DoRop3: Need Invert ROP")); } else { InvertMix2 = FALSE; SDMix = (DWORD)Rop3ToSDMix[Rop3]; } if (psoTmp) { rclTmp.left = rclTmp.top = 0; rclTmp.right = psoTmp->sizlBitmap.cx; rclTmp.bottom = psoTmp->sizlBitmap.cy; } Flags = GET_SDMIX_MIX2F(SDMix); Count = (UINT)GET_MIX2F_COUNT(Flags); Ok = TRUE; PLOTDBG(DBG_ROP3, ("SDMix=%08lx, Flags=%02x, Count=%u", SDMix, Flags, Count)); if (Flags & MIX2F_MUL_DST) { PLOTWARN(("DoRop3: *** Rop3=%08lx Has Multiple DEST, Mix2s NOT complete ***", Rop3)); } while ((Ok) && (Count--)) { Mix2 = (DWORD)(SDMix & MIX2_MASK); if ((!Count) && (InvertMix2)) { PLOTDBG(DBG_ROP3, ("DoRop3: Invert Last MIX2 %02lx -> %02lx", Mix2, Mix2 ^ MIX2_MASK)); Mix2 ^= MIX2_MASK; } PLOTDBG(DBG_ROP3, ("DoRop3: SD=%02lx, Mix2=%02lx", SDMix & MIXSD_MASK, Mix2)); switch (SDMix & MIXSD_MASK) { case MIXSD_SRC_DST: PLOTASSERT(1, "DoRop3: MIXSD_SRC_DST but psoSrc = NULL, Rop3=%08lx", psoSrc, Rop3); Ok = DoMix2(pPDev, psoDst, psoSrc, pco, pxlo, prclDst, prclSrc, NULL, Mix2); break; case MIXSD_PAT_DST: if (psoPat) { Ok = DoMix2(pPDev, psoDst, psoPat, pco, NULL, prclDst, prclPat, pptlPatOrg, Mix2); } else { // // A compatible brush object is passed, use DoFill() to do // the actual work. // Mix2 += 1; Mix2 = MixToRop4(Mix2 | (Mix2 << 8)); PLOTDBG(DBG_ROP3, ("DoRop3: DoFill[%04lx] (%ld, %ld)-(%ld, %ld)=%ld x %ld", Mix2, prclDst->left, prclDst->top, prclDst->right, prclDst->bottom, prclDst->right - prclDst->left, prclDst->bottom - prclDst->top)); Ok = DoFill(psoDst, // psoDst NULL, // psoSrc pco, // pco NULL, // pxlo prclDst, // prclDst NULL, // prclSrc pbo, // pbo pptlPatOrg, // pptlBrushOrg Mix2); // Rop4 } break; case MIXSD_SRC_PAT: PLOTASSERT(1, "DoRop3: MIXSD_SRC_PAT but psoSrc = NULL, Rop3=%08lx", psoSrc, Rop3); PLOTASSERT(1, "DoRop3: MIXSD_SRC_PAT but psoPat = NULL, Rop3=%08lx", psoPat, Rop3); PLOTASSERT(1, "DoRop3: MIXSD_SRC_PAT but psoTmp = NULL, Rop3=%08lx", psoTmp, Rop3); // // Firs tile the pattern onto the temp buffer then do SRC/DST // using SRCCOPY = MIX2_S // if (pptlPatOrg) { // // This is a real pattern we have to tile and align it onto the // desination, but since psoTmp is 0,0 - cx,cy we must alter // the pptlPatOrg to make it align correctly. // pptlPatOrg->x -= prclDst->left; pptlPatOrg->y -= prclDst->top; } Ok = DoMix2(pPDev, psoTmp, psoPat, NULL, NULL, &rclTmp, prclPat, pptlPatOrg, MIX2_S); if (pptlPatOrg) { pptlPatOrg->x += prclDst->left; pptlPatOrg->y += prclDst->top; } // // Now We will do the MIX2 operation between SRC and PAT // if (Ok) { Ok = DoMix2(pPDev, psoTmp, psoSrc, NULL, NULL, &rclTmp, prclSrc, NULL, Mix2); } break; case MIXSD_TMP_DST: PLOTASSERT(1, "DoRop3: MIXSD_TMP_DST but psoTmp = NULL, Rop3=%08lx", psoTmp, Rop3); // // Since we already aligned the pattern on the temp buffer // we can just do the mix2 without aligning it again. // Ok = DoMix2(pPDev, psoDst, psoTmp, pco, NULL, prclDst, &rclTmp, NULL, Mix2); break; } SDMix >>= SDMIX_SHIFT_COUNT; } if (!Ok) { PLOTERR(("DoRop3: FAILED in DoMix2() operations")); } return(Ok); }
UINT CreateFormOI( PPRINTERINFO pPI, POPTITEM pOptItem, POIDATA pOIData ) /*++ Routine Description: This function add the available forms to the combo box, it will optionally add the roll feed type of form Arguments: pPI - Pointer to the PRINTERINFO data structure pOptItem - Pointer to the FORM's OPTITEM pOIData - Pointer to the OIDATA structure Return Value: The form selected, a netavie number means error Author: 09-Dec-1993 Thu 14:35:59 created 06-Nov-1995 Mon 12:56:24 updated Re-write for the New UI Revision History: --*/ { LPWSTR pwSelName; POPTPARAM pOptParam; PFORM_INFO_1 pFI1; PFORMSRC pFS; ENUMFORMPARAM EFP; DWORD i; LONG Sel; DWORD cRollPaper; EXTRAINFO EI; if (!pOptItem) { return(1); } pwSelName = (LPWSTR)((pPI->Flags & PIF_DOCPROP) ? pPI->PlotDM.dm.dmFormName : pPI->CurPaper.Name); PLOTDBG(DBG_FORMS, ("Current Form: <%ws>", pwSelName)); EFP.pPlotDM = &(pPI->PlotDM); EFP.pPlotGPC = pPI->pPlotGPC; if (!PlotEnumForms(pPI->hPrinter, NULL, &EFP)) { PLOTERR(("CreateFormOI: PlotEnumForms() failed")); return(0); } cRollPaper = 0; if ((!(pPI->Flags & PIF_DOCPROP)) && (pPI->pPlotGPC->Flags & PLOTF_ROLLFEED)) { // // Add device' roll paper to the combo box too. // PLOTDBG(DBG_FORMS, ("Device support ROLLFEED so add RollPaper if any")); for (i= 0, pFS = (PFORMSRC)pPI->pPlotGPC->Forms.pData; i < (DWORD)pPI->pPlotGPC->Forms.Count; i++, pFS++) { if (!pFS->Size.cy) { ++cRollPaper; } } } PLOTDBG(DBG_FORMS, ("Valid Count is %ld [%ld + %ld] out of %ld", EFP.ValidCount + cRollPaper, EFP.ValidCount, cRollPaper, EFP.Count)); EI.Size = (DWORD)(cRollPaper * (sizeof(WCHAR) * CCHFORMNAME)); if (!CreateOPTTYPE(pPI, pOptItem, pOIData, EFP.ValidCount + cRollPaper, &EI)) { LocalFree((HLOCAL)EFP.pFI1Base); return(0); } pPI->pFI1Base = EFP.pFI1Base; pOptItem->pOptType->Style = OTS_LBCB_SORT; pOptParam = pOptItem->pOptType->pOptParam; for (i = 0, Sel = 0, pFI1 = EFP.pFI1Base; i < EFP.Count; i++, pFI1++) { if (pFI1->Flags & FI1F_VALID_SIZE) { pOptParam->cbSize = sizeof(OPTPARAM); pOptParam->Style = (pPI->pPlotGPC->Flags & PLOTF_PAPERTRAY) ? FS_TRAYPAPER : 0; pOptParam->pData = pFI1->pName; pOptParam->IconID = (pFI1->Flags & FI1F_ENVELOPE) ? IDI_CPSUI_ENVELOPE : IDI_CPSUI_STD_FORM; pOptParam->lParam = (LONG)i; if (!lstrcmp(pwSelName, pOptParam->pData)) { pOptItem->Sel = Sel; } pOptParam++; Sel++; } } if (cRollPaper) { LPWSTR pwStr = (LPWSTR)EI.pData; size_t cchpwStr = EI.Size / sizeof(WCHAR); // // Add device' roll paper to the combo box too. // for (i = 0, pFS = (PFORMSRC)pPI->pPlotGPC->Forms.pData; i < (DWORD)pPI->pPlotGPC->Forms.Count; i++, pFS++) { if (!(pFS->Size.cy)) { // // Got one, we have to translated into the UNICODE first // pOptParam->cbSize = sizeof(OPTPARAM); pOptParam->Style = FS_ROLLPAPER; pOptParam->pData = (LPTSTR)pwStr; pwStr += CCHFORMNAME; cchpwStr -= CCHFORMNAME; pOptParam->IconID = IDI_ROLLPAPER; pOptParam->lParam = (LONG)i; str2Wstr(pOptParam->pData, cchpwStr, pFS->Name); if (!lstrcmp(pwSelName, pOptParam->pData)) { pOptItem->Sel = Sel; } pOptParam++; Sel++; } } } return(1); }
BOOL GetFormSelect( PPRINTERINFO pPI, POPTITEM pOptItem ) /*++ Routine Description: This function retrieve the form selected by the user from the combo box Arguments: pPI - Pointer to the PRINTERINFO pOptItem - Pointer to the FORM's OPTITEM Return Value: TRUE if sucessful and pPI will be set correctly, FALSE if error occurred Author: 09-Dec-1993 Thu 14:44:18 created 18-Dec-1993 Sat 03:55:30 updated Changed dmFields setting for the PAPER, now we will only set the DM_FORMNAME field, this way the returned document properties will be always in known form even user defines many forms in spooler. 06-Nov-1995 Mon 12:56:00 updated Re-write for the New UI Revision History: --*/ { PAPERINFO CurPaper; POPTPARAM pOptParam; pOptParam = pOptItem->pOptType->pOptParam + pOptItem->Sel; if (pOptParam->Style == FS_ROLLPAPER) { PFORMSRC pFS; // // This was added from the GPC data for the roll feed // PLOTASSERT(0, "GetComboBoxSelForm: INTERNAL ERROR, ROLLPAPER In document properties", !(pPI->Flags & PIF_DOCPROP), 0); PLOTASSERT(0, "GetComboBoxSelForm: INTERNAL ERROR, device CANNOT have ROLLPAPER", pPI->pPlotGPC->Flags & PLOTF_ROLLFEED, 0); PLOTDBG(DBG_FORMS, ("Roll Feed Paper is selected, (%ld)", pOptParam->lParam)); if ((pOptParam->lParam >= 0) && ((DWORD)(pOptParam->lParam) < (DWORD)pPI->pPlotGPC->Forms.Count)) { pFS = (PFORMSRC)pPI->pPlotGPC->Forms.pData + pOptParam->lParam; // // Since the RollFeed paper has variable length, and the cy is set // to zero at GPC data, we must take that into account // CurPaper.Size = pFS->Size; CurPaper.ImageArea.left = pFS->Margin.left; CurPaper.ImageArea.top = pFS->Margin.top; CurPaper.ImageArea.right = CurPaper.Size.cx - pFS->Margin.right; CurPaper.ImageArea.bottom = pPI->pPlotGPC->DeviceSize.cy - pFS->Margin.bottom; str2Wstr(CurPaper.Name, CCHOF(CurPaper.Name), pFS->Name); } else { PLOTERR(("GetComboBoxSelForm: Internal Error, Invalid lParam=%ld", pOptParam->lParam)); return(FALSE); } } else { FORM_INFO_1 *pFI1; DWORD cb; // // This form is in the form data base // pFI1 = pPI->pFI1Base + pOptParam->lParam; CurPaper.Size = pFI1->Size; CurPaper.ImageArea = pFI1->ImageableArea; WCPYFIELDNAME(CurPaper.Name, CCHOF(CurPaper.Name), pFI1->pName); } // // Now we have current paper validated // if (pPI->Flags & PIF_DOCPROP) { // // Turn off first, then turn on paper fields as needed // pPI->PlotDM.dm.dmFields &= ~DM_PAPER_FIELDS; pPI->PlotDM.dm.dmFields |= (DM_FORMNAME | DM_PAPERSIZE); // // Copy down the dmFormName, dmPaperSize and set dmPaperWidth/Length, // the fields for PAPER will bb set to DM_FORMNAME so that we always // can find the form also we may set DM_PAPERSIZE if index number is // <= DMPAPER_LAST // WCPYFIELDNAME(pPI->PlotDM.dm.dmFormName, CCHOF(pPI->PlotDM.dm.dmFormName), CurPaper.Name); pPI->PlotDM.dm.dmPaperSize = (SHORT)(pOptParam->lParam + DMPAPER_FIRST); pPI->PlotDM.dm.dmPaperWidth = SPLTODM(CurPaper.Size.cx); pPI->PlotDM.dm.dmPaperLength = SPLTODM(CurPaper.Size.cy); #if DBG *(PRECTL)&pPI->PlotDM.dm.dmBitsPerPel = CurPaper.ImageArea; #endif } else { pPI->CurPaper = CurPaper; } PLOTDBG(DBG_FORMS, ("*** GetComboBoxSelForm from COMBO = '%s'", CurPaper.Name)); PLOTDBG(DBG_FORMS, ("Size=%ld x %ld", CurPaper.Size.cx, CurPaper.Size.cy)); PLOTDBG(DBG_FORMS, ("ImageArea=(%ld, %ld) - (%ld, %ld)", CurPaper.ImageArea.left, CurPaper.ImageArea.top, CurPaper.ImageArea.right, CurPaper.ImageArea.bottom)); return(TRUE); }
DWORD ValidateSetPLOTDM( HANDLE hPrinter, PPLOTGPC pPlotGPC, LPWSTR pwDeviceName, PPLOTDEVMODE pPlotDMIn, PPLOTDEVMODE pPlotDMOut, PFORMSIZE pCurForm ) /*++ Routine Description: This function set and validate the pPlotDMOut from pPlotDMIn (if not null and valid) Arguments: hPrinter - Handle to the printer to be checked pPlotGPC - The plotter's GPC data loaded from the file pwDeviceName - Device Name to be put into dmDeviceName, if NULL then the device name is set from pPlotGPC->DeviceName pPlotDMIn - pointer to the input PLOTDEVMODE data structure, if can be NULL pPlotDMOut - Pointer to the output PLOTDEVMODE data structure, if pPlotDMIn is NULL then a default PLOTDEVMODE is returned pCurForm - Pointer to the FORMSIZE data structure which will be updated if the pointer is not NULL, the final result of the form size/imagable area selected by the user will be written to here. the form name will be in pPlotDM->dmFormName. Return Value: the return value is a DWORD dmField error code which specified dmFields are invalid (DM_xxxxx in wingdi.h) if the return value has any DM_INV_xxx bits set then it should raised an error to the user. if return value is 0 then function sucessful Author: 23-Nov-1993 Tue 10:08:50 created -by- Daniel Chou (danielc) 15-Dec-1993 Wed 21:27:52 updated -by- Daniel Chou (danielc) Fixed bug which compare dmPaperWidth/Length to MIN_SPL_FORM_CX 18-Dec-1993 Sat 03:57:24 updated -by- Daniel Chou (danielc) Fixed bug which reset dmFields when we checking DM_PAPERxxx and DM_FORMNAME, this turn off DM_ORIENTATION fields which let the orientation setting never stick. Also change how this fucntion set the paper fields, this function now only set DM_FORMNAME upon returned if the dmPaperSize getting larger then DMPAPER_LAST, otherwise it set DM_FORMNAME | DM_PAPERSIZE 12-Apr-1994 Tue 15:07:24 updated -by- Daniel Chou (danielc) Make smaller spec version printable 25-Oct-1994 Tue 13:41:03 updated -by- Daniel Chou (danielc) Change to have default as current Printer Properties setting first, Revision History: --*/ { DWORD dmErrFields = 0; PLOTASSERT(1, "ValidatePLOTDM: NULL pPlotDMOut", pPlotDMOut, 0); PLOTASSERT(1, "ValidatePLOTDM: NULL pPlotGPC", pPlotGPC, 0); if ((pPlotDMOut) || (pPlotGPC)) { PPRINTER_INFO_2 pPrinter2 = NULL; DWORD cbNeed; DWORD cbRet; // // First: set the default PLOTDEVMODE for the output then from there // validate/settting from input devmode, if pwDeviceName passed // as NULL then it assume that pPlotDMOut alreay set and // validated // if (pwDeviceName) { SetDefaultPLOTDM(hPrinter, pPlotGPC, pwDeviceName, pPlotDMOut, pCurForm); PLOTDBG(DBG_DEFDEVMODE, ("ValidateSetPLOTDM: Set Default PLOTDM DeviceName=%ls", pwDeviceName)); } // // Now see if we can get the current printman devmode setting as default // cbNeed = cbRet = 0; if ((!xGetPrinter(hPrinter, 2, NULL, 0, &cbNeed)) && (xGetLastError() == ERROR_INSUFFICIENT_BUFFER) && (pPrinter2 = LocalAlloc(LMEM_FIXED, cbNeed)) && (xGetPrinter(hPrinter, 2, (LPBYTE)pPrinter2, cbNeed, &cbRet)) && (cbNeed == cbRet) && (pPrinter2->pDevMode)) { PLOTDBG(DBG_DEFDEVMODE, ("ValidateSetPLOTDM: Got the PrintMan DEVMODE")); dmErrFields = MergePLOTDM(hPrinter, pPlotGPC, (PPLOTDEVMODE)pPrinter2->pDevMode, pPlotDMOut, pCurForm); } else { PLOTWARN(("ValidateSetPLOTDM: CANNOT get the PrintMan's DEVMODE")); PLOTWARN(("pPrinter2=%08lx, pDevMode=%08lx, cbNeed=%ld, cbRet=%ld, LastErr=%ld", pPrinter2, (pPrinter2) ? pPrinter2->pDevMode : 0, cbNeed, cbRet, xGetLastError())); } if (pPrinter2) { LocalFree((HLOCAL)pPrinter2); } // // Now the pPlotDMOut is validated, merge it with user's request // if (pPlotDMIn) { dmErrFields = MergePLOTDM(hPrinter, pPlotGPC, pPlotDMIn, pPlotDMOut, pCurForm); } } return(dmErrFields); }
BOOL IsA4PaperDefault( VOID ) /*++ Routine Description: This function determine if the machine user is using the letter or A4 paper as default based on the country code Arguments: NONE Return Value: BOOL true if the country default paper is A4, else LETTER Author: 23-Nov-1993 Tue 17:50:25 created -by- Daniel Chou (danielc) 02-Feb-1994 Wed 03:01:12 updated -by- Daniel Chou (danielc) re-written so that we do open registry for the international data ourself, and we will make sure we close the all the keys opened by this function, so the system can unload the registry when the user log off. Revision History: --*/ { #if HAS_GETREGDATA HKEY hKey; LONG CountryCode = DEFAULT_COUNTRY; WCHAR wszStr[16]; if (RegOpenKey(HKEY_CURRENT_USER, wszCountryKey, &hKey) == ERROR_SUCCESS) { DWORD Type = REG_SZ; DWORD RetVal = sizeof(wszStr); if (RegQueryValueEx(hKey, (LPTSTR)wszCountryValue, NULL, &Type, (LPBYTE)wszStr, &RetVal) == ERROR_SUCCESS) { LPWSTR pwStop; PLOTDBG(DBG_A4DEFAULT, ("IsA4PaperDefault: Country = %s", wszStr)); CountryCode = wcstoul(wszStr, &pwStop, 10); } else { PLOTERR(("IsA4PaperDefault: RegQueryValue '%s' FAILED", wszCountryValue)); } RegCloseKey(hKey); } else { PLOTERR(("IsA4PaperDefault: RegOpenKey '%s' FAILED", wszCountryKey)); } // // ***** MAKE SURE we have following line to close the CURRENT USER // RegCloseKey(HKEY_CURRENT_USER); if ((CountryCode == CTRY_UNITED_STATES) || (CountryCode == CTRY_CANADA) || ((CountryCode >= 50) && (CountryCode < 60)) || ((CountryCode >= 500) && (CountryCode < 600))) { PLOTDBG(DBG_A4DEFAULT, ("IsA4PaperDefault = No, Use 'LETTER'")); return(FALSE); } else { PLOTDBG(DBG_A4DEFAULT, ("IsA4PaperDefault = Yes")); return(TRUE); } #else // // Use letter size now // return(FALSE); #endif // HAS_GETREGDATA }
SHORT GetDefaultPaper( PPAPERINFO pPaperInfo ) /*++ Routine Description: This function compute the default paper name, size. Arguments: pPaperInfo - Point to the paper info which will be fill by this function Return Value: It return a SHORT value which specified the standard paper index in as DMPAPER_xxx Author: 03-Dec-1993 Fri 13:13:42 created Revision History: --*/ { SHORT dmPaperSize; HRESULT hr; if (pPaperInfo == NULL) { return 0; } pPaperInfo->ImageArea.left = pPaperInfo->ImageArea.top = 0; if (IsA4PaperDefault()) { dmPaperSize = (SHORT)DMPAPER_A4; pPaperInfo->Size.cx = pPaperInfo->ImageArea.right = DMTOSPL(A4_FORM_CX); pPaperInfo->Size.cy = pPaperInfo->ImageArea.bottom = DMTOSPL(A4_FORM_CY); hr = StringCchCopy(pPaperInfo->Name, CCHOF(pPaperInfo->Name), A4_FORM_NAME); if (FAILED(hr) ) { PLOTASSERT(0, "Couldn't copy the string %ls to pPaperInfo", SUCCEEDED(hr), A4_FORM_NAME); } PLOTDBG(DBG_DEFPAPER, ("Pick 'A4' paper as default")); } else { dmPaperSize = (SHORT)DMPAPER_LETTER; pPaperInfo->Size.cx = (LONG)_DefPlotDM.dm.dmPaperWidth; pPaperInfo->Size.cy = (LONG)_DefPlotDM.dm.dmPaperLength; dmPaperSize = (SHORT)DMPAPER_LETTER; pPaperInfo->Size.cx = pPaperInfo->ImageArea.right = DMTOSPL(_DefPlotDM.dm.dmPaperWidth); pPaperInfo->Size.cy = pPaperInfo->ImageArea.bottom = DMTOSPL(_DefPlotDM.dm.dmPaperLength); hr = StringCchCopy(pPaperInfo->Name, CCHOF(pPaperInfo->Name), _DefPlotDM.dm.dmFormName); if (FAILED(hr) ) { PLOTASSERT(0, "Couldn't copy the string %ls to pPaperInfo", SUCCEEDED(hr), _DefPlotDM.dm.dmFormName); } PLOTDBG(DBG_DEFPAPER, ("Pick 'Letter' paper as default")); } PLOTDBG(DBG_DEFPAPER, ("SetDefaultPaper: '%ls' (%ld x %ld)", pPaperInfo->Name, pPaperInfo->Size.cx, pPaperInfo->Size.cy)); return(dmPaperSize); }
VOID SetDefaultPLOTDM( HANDLE hPrinter, _In_ PPLOTGPC pPlotGPC, _In_opt_ LPCWSTR pwDeviceName, _In_ PPLOTDEVMODE pPlotDM, _Out_opt_ PFORMSIZE pCurForm ) /*++ Routine Description: This function set the default devmode based on the current pPlotGPC Arguments: hPrinter - Handle to the printer pPlotGPC - our loaded/verified GPC data. pwDeviceName - the device name passed in pPlotDM - Pointer to our ExtDevMode pCurForm - Pointer to the FORMSIZE data structure which will be updated if the pointer is not NULL, the final result of the form size/imagable area selected by the user will be written to here. the form name will be in pPlotDM->dmFormName. Return Value: VOID Author: 14-Dec-1993 Tue 20:21:48 updated Update the dmScale based on maximum the device can support 06-Dec-1993 Mon 12:49:52 updated make sure we turn off the DM_xxx bits if one of those is not valid or supported in current plotter 16-Nov-1993 Tue 13:49:27 created Revision History: --*/ { WCHAR *pwchDeviceName = NULL; ULONG ulStrLen = 0; UNREFERENCED_PARAMETER(hPrinter); // // Device name including NULL terminator // must be equal or shorter than CCHDEVICENAME. // PREFIX doesn' take this assumption. Buffer size needs to be flexible and // should not be on stack. // if (pwDeviceName) { ulStrLen = (ULONG)wcslen(pwDeviceName); // // Allocate buffer to hold pwDeviceName including null terminator. // Make sure that pwDeviceName has a device name. // if (0 == ulStrLen || !(pwchDeviceName = (WCHAR*)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, (ulStrLen + 1) * sizeof(WCHAR)))) { PLOTERR(("SetDefaultPLOTDM: memory allocaton failed.\n")); // // Make sure that pPlotGPC->DeviceName has a null terminator. // pPlotGPC->DeviceName[0] = (BYTE)'\0'; } else { _WCPYSTR_FILL_TRAIL_WITH_NULL(pwchDeviceName, ulStrLen + 1, pwDeviceName); // // Make sure the PlotGPC's device name is ssync with the pDeviceName // passed. // String length must be equal or shorter than CCHDEVICENAME. // DEVMODE's device name and pPlotGPC->DeviceName can't hold a sting // longer than CCHDEVICENAME. // if (ulStrLen + 1 > CCHDEVICENAME) { PLOTERR(("SetDefaultPLOTDM: DeviceName is longer than buffer size.\n")); } else { WStr2Str(pPlotGPC->DeviceName, CCHOF(pPlotGPC->DeviceName), pwchDeviceName); } } PLOTDBG(DBG_DEFDEVMODE, ("PlotGPC DeviceName=%hs\npwDeviceName=%ls", pPlotGPC->DeviceName, pwDeviceName)); } else { PLOTERR(("No DeviceName passed, using GPC's '%hs'", pPlotGPC->DeviceName)); ulStrLen = (ULONG)strlen(pPlotGPC->DeviceName); // // Allocate buffer to hold pwDeviceName including null terminator. // Make sure that pwDeviceName has a device name. // if (0 == ulStrLen || !(pwchDeviceName = (WCHAR*)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, (ulStrLen + 1) * sizeof(WCHAR)))) { PLOTERR(("SetDefaultPLOTDM: memory allocaton failed.\n")); } else { str2Wstr(pwchDeviceName, ulStrLen + 1, pPlotGPC->DeviceName); } } // // Make a default copy first then copy device name down // CopyMemory(pPlotDM, &_DefPlotDM, sizeof(PLOTDEVMODE)); if (pwchDeviceName) { WCPYFIELDNAME(pPlotDM->dm.dmDeviceName, CCHOF(pPlotDM->dm.dmDeviceName), pwchDeviceName); LocalFree(pwchDeviceName); } else { pPlotDM->dm.dmDeviceName[0] = L'\0'; } // // We must turn off the DM_xxx bits in dmFields if we do not support it, // look at default fields we copy down then update it // if (pPlotGPC->MaxScale) { if ((WORD)pPlotDM->dm.dmScale > pPlotGPC->MaxScale) { pPlotDM->dm.dmScale = (SHORT)pPlotGPC->MaxScale; } } else { pPlotDM->dm.dmFields &= ~DM_SCALE; } if (pPlotGPC->MaxCopies <= 1) { pPlotDM->dm.dmFields &= ~DM_COPIES; } if (!(pPlotGPC->MaxQuality)) { pPlotDM->dm.dmFields &= ~DM_PRINTQUALITY; } // // DEFAULT 50% quality for byte align plotter (DJ 600) to do ROP right // if (pPlotGPC->Flags & PLOTF_RASTERBYTEALIGN) { pPlotDM->dm.dmPrintQuality = DMRES_LOW; PLOTWARN(("SetDefaultPLOTDM: Force Default Qaulity = DMRES_LOW")); } if (!(pPlotGPC->Flags & PLOTF_COLOR)) { if (pPlotGPC->Flags & PLOTF_RASTER) { pPlotDM->dm.dmFields &= ~DM_COLOR; pPlotDM->dm.dmColor = DMCOLOR_MONOCHROME; } else { PLOTASSERT(0, "SetDefaultPLOTDM: The Pen Ploter CANNOT be MONO.", (pPlotGPC->Flags & PLOTF_COLOR), 0); pPlotGPC->Flags |= PLOTF_COLOR; } } // // Set default form name based on the country/region // SetDefaultDMForm(pPlotDM, pCurForm); }
PPDEV ValidatePDEVFromSurfObj( SURFOBJ *pso ) /*++ Routine Description: This function validates the PDEV to see if it belong to this driver and checks to see if it is still usable. It also moves the passed SURFOBJ in the data structure which is needed for the driver to occasionally call EngCheckAbort, to see if the job has been cancelled. Arguments: pPDev - Pointer to the PDEV data structure to be validate Return Value: return the passed in PDEV pointer if sucessful, return NULL if failed, if it return NULL it will also log the INVALID_HANDLE error code Author: 30-Nov-1993 Tue 20:39:12 created Revision History: --*/ { PPDEV pPDev; pPDev = ((PPDEV)(((SURFOBJ *)pso)->dhpdev)); if (pPDev) { // // Look for start marker, size of the data structure, and end marker. // if (pPDev->PDEVBegID == PDEV_BEG_ID) { if (pPDev->SizePDEV == sizeof(PDEV)) { if (pPDev->PDEVEndID == PDEV_END_ID) { // // Okay its valid so record the surfobj so we can call // EngCheckAbort() in our output functions // pPDev->pso = pso; // // Check to see if the app or the spooler has canceled // the job, if it has set our cancel bit and fail this // call. // if (EngCheckAbort(pso)) { pPDev->Flags |= PDEVF_CANCEL_JOB; PLOTDBG(DBG_VALIDATE_PDEV, ("ValidatePDEV: EngCheckAbort returns TRUE")); return(NULL); } return(pPDev); } else { PLOTRIP(("ValidatePDEV: Invalid PDEV End ID (%08lx)", pPDev->PDEVEndID)); } } else { PLOTRIP(("ValidatePDEV: Invalid PDEV size (%ld)", pPDev->SizePDEV)); } } else { PLOTRIP(("ValidatePDEV: Invalid PDEV Begin ID (%08lx)", pPDev->PDEVBegID)); } } else { PLOTRIP(("ValidatePDEV: NULL pPDev")); } SetLastError(ERROR_INVALID_HANDLE); return(NULL); }
BOOL DoStrokePathByEnumingClipLines( PPDEV pPDev, SURFOBJ *pso, CLIPOBJ *pco, PATHOBJ *ppo, PPOINTL pptlBrushOrg, BRUSHOBJ *pbo, ROP4 rop4, LINEATTRS *plineattrs ) /*++ Routine Description: Strokes a path through a complex clipping region by utilizing the engine helper functions. This is done because there is no way to fail a DrvStrokePath and have it come back in any simpler format by the NT graphics engine. In general, we can fail DrvXXX calls and the NT graphic engine will simply the object to draw, then call back into the driver. Stroking a path however cannot be simplified any more, so the best we can hope for is having the PATHOBJ converted to straight line segments (removing BEZIERS if present). We then must stroke the path ourselves, using the provided EngXXX helpers. Since helper functions exist that allow us to to enumerate the portions of a path as CLIPLINE segments that fall within the clipping region, we do that here, thus stroking the segments that lie inside of the passed CLIPOBJ. Arguments: pPDev Pointer to the current PDEV pso SURFOBJ to write to pco CLIPOBJ to use when enuming paths ppo PATHOBJ to stroke through clip path pptlBrushOrg BRUSH origin pbo BRUSH to stroke with rop4 ROP4 to use plineattrs LINEATTRS structure that describes the styling for the line Return Value: TRUE if sucessful FALSE if failed, If the path we are asked to stroke contains BEZIERS, this function will fail in order to allow the Engine to break the path down to line segments. Author: 2/01/94 JB Revision History: --*/ { PLOT_CLIPLINE PlotClipLine; CLIPLINE *pCurClipLine; RUN *pCurRun; POINTFIX ptsfx[2]; POINTL ptlCur; FIX iStartInFX; FIX iStopInFX; LONG dx; LONG dy; LONG i; BOOL bMore; BOOL bXordered; BOOL bFlipX; BOOL bFlipY; // // First check for Beziers and if we have them fail the call since we // want straight line segments to stroke, with the appropriate style // if (ppo->fl & PO_BEZIERS) { PLOTDBG(DBG_STROKECLIPLINES, ("DoStrokePathByEnumingClipLines:Path had BEZ returning FALSE")); return(FALSE); } PLOTDBG(DBG_STROKECLIPLINES, ("DoStrokeByEnumingClipLines: NO CLIPOBJ %p", (pco != NULL) , (LONG_PTR)pco)); PLOTDBG(DBG_STROKECLIPLINES, ("DoStrokeByEnumingClipLines: CLIPOBJ is TRIVIAL (%lx)", (pco->iDComplexity != DC_TRIVIAL) , (LONG)pco->iDComplexity )); // // Send out the line attributes , so the residue will be calculated // correctly // DoSetupOfStrokeAttributes(pPDev, pptlBrushOrg, pbo, rop4, NULL); // // Initiate enumeration of the CLIPLINES by calling the Engine helper // PATHOBJ_vEnumStartClipLines(ppo, pco, pso, plineattrs); // // Start a loop to enum through all the available CLIPLINE structures // pCurClipLine = (CLIPLINE *)&PlotClipLine; do { // // Get the first batch of CLIPLINE structures then go to work on them // bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(PlotClipLine), pCurClipLine); // // Calculate dx and dy in order to determine if the line is Xordered or // Yordered this is needed because of the way the engine passes us RUNS // if dx > dy then the line is said to be Xordered and thus any given // RUN iStart and iStop values is a projection on the x axis. Given this // informatino we can calculate the adjoining Y coordinate and draw the // line appropriately. // dx = pCurClipLine->ptfxB.x - pCurClipLine->ptfxA.x; dy = pCurClipLine->ptfxB.y - pCurClipLine->ptfxA.y; if ( bFlipX = (dx < 0 )) { dx = -dx; } if ( bFlipY = (dy < 0 )) { dy = -dy; } // // Now calculate if the line is x ordered or y ordered // bXordered = (dx >= dy); PLOTDBG(DBG_STROKECLIPLINES, ("DoStrokePathByEnumingClipLines:Compute ClipLine runs=%u, xordered %d", pCurClipLine->c, bXordered )); // // Enum through all the given RUNS drawing with the pen down between any // iStart and iStop value in each RUN // for (i = 0, pCurRun = &(pCurClipLine->arun[0]); i < (LONG)pCurClipLine->c; i++, pCurRun++) { // // The value of iStart and iStop are always positive!! so // we must handle it ourselves, so the correct thing happens // iStartInFX = LTOFX(pCurRun->iStart); iStopInFX = LTOFX(pCurRun->iStop); if (bFlipX ) { ptsfx[0].x = -iStartInFX; ptsfx[1].x = -iStopInFX; } else { ptsfx[0].x = iStartInFX; ptsfx[1].x = iStopInFX; } if (bFlipY ) { ptsfx[0].y = -iStartInFX; ptsfx[1].y = -iStopInFX; } else { ptsfx[0].y = iStartInFX; ptsfx[1].y = iStopInFX; } // // We must output the correct line attributes structure with the // correct calculated residue in order for this to work correctly // HandleLineAttributes(pPDev, plineattrs, &pCurClipLine->lStyleState, pCurRun->iStart); // // The calculations for the opposing coordinate varies based on the // ordering of the line. If the line is Xordered we calculate the // Y value, if itsYordered we calculate the X value. We do this // in order to determine the correct target coordinate. Since the // RUN is given to us as START and STOP, we must manually determine // what coordinate this represents inside the device coordinate // space. If the RUN is xordered, the x-coordinate is correct, and // the y-coordinate must be projected based on the ratio. // if (bXordered) { ptsfx[0].x += pCurClipLine->ptfxA.x; ptsfx[0].y = MulDiv( ptsfx[0].y, dy, dx) + pCurClipLine->ptfxA.y; ptsfx[1].x += pCurClipLine->ptfxA.x; ptsfx[1].y = MulDiv( ptsfx[1].y, dy, dx) + pCurClipLine->ptfxA.y; } else { ptsfx[0].x = MulDiv(ptsfx[0].x, dx, dy) + pCurClipLine->ptfxA.x; ptsfx[0].y += pCurClipLine->ptfxA.y; ptsfx[1].x = MulDiv(ptsfx[1].x, dx, dy) + pCurClipLine->ptfxA.x; ptsfx[1].y += pCurClipLine->ptfxA.y; } // // Do PE with pen up first, in order to move to the starting // position. // OutputString(pPDev, "PE<"); if (!i) { // // If we are at first point then output that now. // ptlCur.x = ptlCur.y = 0; OutputString(pPDev, "="); } // // Stroke the segment with the pen down. // OutputXYParams(pPDev, (PPOINTL)ptsfx, (PPOINTL)NULL, (PPOINTL)&ptlCur, (UINT)2, (UINT)1, 'F'); OutputString(pPDev, ";"); } } while (bMore); // While we need to enum again.. return(TRUE); }
BOOL MovePen( PPDEV pPDev, PPOINTFIX pPtNewPos, PPOINTL pPtDevPos ) /*++ Routine Description: This function sends the HPGL code for the requested pen. Arguments: pPDev - Pointer to the PDEV data structure pPtNewPos - The location pen will move to, this is in 28.4 fix notation pPtDevPos - The new device coordinate device position Return Value: TRUE if sucessful FALSE otherwise Author: 1:04 on Tue 7 Nov 1989 Added this commentary, and area fill optimization code. 30-Nov-1993 Tue 22:05:32 updated Update, commented and clean up style 16-Feb-1994 Wed 17:10:54 updated Re-write to get rid of the physical position Revision History: --*/ { POINTL ptDevPos; ptDevPos.x = FXTODEVL(pPDev, pPtNewPos->x); ptDevPos.y = FXTODEVL(pPDev, pPtNewPos->y); if (pPtDevPos) { *pPtDevPos = ptDevPos; } PLOTDBG( DBG_MOVEPEN, ("MovePen: Moving Absolute to FIX = [X=%d,%d] Device = [X=%d, Y=%d]", pPtNewPos->x, pPtNewPos->y, ptDevPos.x, ptDevPos.y )); return(OutputFormatStr(pPDev, "PE<=#D#D;", ptDevPos.x, ptDevPos.y)); }
BOOL GetPlotRegData( HANDLE hPrinter, LPBYTE pData, DWORD RegIdx ) /*++ Routine Description: This function retrieve from registry to the pData Arguments: hPrinter - Handle to the printer interested pData - Pointer to the data area buffer, it must large enough RegIdx - One of the PRKI_xxxx in LOWORD(Index), HIWORD(Index) specified total count for the PENDATA set Return Value: TRUE if sucessful, FALSE if failed, Author: 06-Dec-1993 Mon 22:22:47 created -by- Daniel Chou (danielc) 10-Dec-1993 Fri 01:13:14 updated -by- Daniel Chou (danielc) Fixed nesty problem in spooler of GetPrinterData which if we passed a pbData and cb but if it cannot get any data then it will clear all our buffer, this is not we expected (we expected it just return error rather clear our buffer). Now we do extended test before we really go get the data. The other problem is, if we set pbData = NULL then spooler always have excption happened even we pass &cb as NULL also. Revision History: --*/ { PPLOTREGKEY pPRK; LONG lRet; DWORD cb; DWORD Type; WCHAR wBuf[32]; PLOTREGKEY PRK; UINT Index; Index = LOWORD(RegIdx); PLOTASSERT(0, "GetPlotRegData: Invalid PRKI_xxx Index %ld", Index <= PRKI_LAST, Index); if (Index >= PRKI_PENDATA1) { UINT cPenData; if ((cPenData = (UINT)HIWORD(RegIdx)) >= MAX_PENPLOTTER_PENS) { PLOTERR(("GetPlotRegData: cPenData too big %ld (Max=%ld)", cPenData, MAX_PENPLOTTER_PENS)); cPenData = MAX_PENPLOTTER_PENS; } PRK.pwKey = GetPenDataKey(wBuf, (WORD)(Index - PRKI_PENDATA1 + 1)); PRK.Size = (DWORD)sizeof(PENDATA) * (DWORD)cPenData; pPRK = &PRK; } else { pPRK = (PPLOTREGKEY)&PlotRegKey[Index]; } // // We must do following sequence or if an error occurred then the pData // will be filled with ZEROs // // 1. Set Type/cb to invalid value // 1. query the type/size of the keyword, (if more data available) // 2. and If size is exact as we want // 3. and if the type is as we want (REG_BINARY) // 4. assume data valid then query it // Type = 0xffffffff; cb = 0; if ((lRet = xGetPrinterData(hPrinter, pPRK->pwKey, &Type, (LPBYTE)pData, 0, &cb)) != ERROR_MORE_DATA) { if (lRet == ERROR_FILE_NOT_FOUND) { PLOTWARN(("GetPlotRegData: GetPrinterData(%ls) not found", pPRK->pwKey)); } else { PLOTERR(("GetPlotRegData: 1st GetPrinterData(%ls) failed, Error=%ld", pPRK->pwKey, lRet)); } } else if (cb != pPRK->Size) { PLOTERR(("GetPlotRegData: GetPrinterData(%ls) Size != %ld (%ld)", pPRK->pwKey, pPRK->Size, cb)); } else if (Type != REG_BINARY) { PLOTERR(("GetPlotRegData: GetPrinterData(%ls) Type != REG_BINARY (%ld)", pPRK->pwKey, Type)); } else if ((lRet = xGetPrinterData(hPrinter, pPRK->pwKey, &Type, (LPBYTE)pData, pPRK->Size, &cb)) == NO_ERROR) { PLOTDBG(DBG_GETREGDATA, ("READ '%ws' REG Data: Type=%ld, %ld bytes", pPRK->pwKey, Type, cb)); return(TRUE); } else { PLOTERR(("GetPlotRegData: 2nd GetPrinterData(%ls) failed, Error=%ld", pPRK->pwKey, lRet)); } return(FALSE); }
BOOL IntersectRECTL( PRECTL prclDest, PRECTL prclSrc ) /*++ Routine Description: This function intersect two RECTL data structures which specified imageable areas. Arguments: prclDest - pointer to the destination RECTL data structure, the result is written back to here prclSrc - pointer to the source RECTL data structure to be intersect with the destination RECTL Return Value: TRUE if destination is not empty, FALSE if final destination is empty Author: 20-Dec-1993 Mon 14:08:02 updated -by- Daniel Chou (danielc) Change return value's meaning as if intersection is not empty 17-Dec-1993 Fri 14:41:10 updated -by- Daniel Chou (danielc) Add prclDif and compare it correctly 29-Nov-1993 Mon 19:02:01 created -by- Daniel Chou (danielc) Revision History: --*/ { BOOL IsNULL = FALSE; if (prclSrc != prclDest) { // // For left/top we will set to whichever is larger. // if (prclDest->left < prclSrc->left) { prclDest->left = prclSrc->left; } if (prclDest->top < prclSrc->top) { prclDest->top = prclSrc->top; } // // For right/bottom we will set to whichever is smaller // if (prclDest->right > prclSrc->right) { prclDest->right = prclSrc->right; } if (prclDest->bottom > prclSrc->bottom) { prclDest->bottom = prclSrc->bottom; } } PLOTDBG(DBG_INTERSECTRECTL, ("IntersectRECTL: Dest = (%ld x %ld)", prclDest->right-prclDest->left, prclDest->bottom-prclDest->top)); return((prclDest->right > prclDest->left) && (prclDest->bottom > prclDest->top)); }
BOOL SetPlotRegData( HANDLE hPrinter, LPBYTE pData, DWORD RegIdx ) /*++ Routine Description: This function save pData to to the registry Arguments: hPrinter - Handle to the printer interested pData - Pointer to the data area buffer, it must large enough RegIdx - One of the PRKI_xxxx in LOWORD(Index), HIWORD(Index) specified total count for the PENDATA set Return Value: TRUE if sucessful, FALSE if failed, Author: 06-Dec-1993 Mon 22:25:55 created -by- Daniel Chou (danielc) Revision History: --*/ { PPLOTREGKEY pPRK; WCHAR wBuf[32]; PLOTREGKEY PRK; UINT Index; Index = (UINT)LOWORD(RegIdx); PLOTASSERT(0, "SetPlotRegData: Invalid PRKI_xxx Index %ld", Index <= PRKI_LAST, Index); if (Index >= PRKI_PENDATA1) { UINT cPenData; if ((cPenData = (UINT)HIWORD(RegIdx)) >= MAX_PENPLOTTER_PENS) { PLOTERR(("GetPlotRegData: cPenData too big %ld (Max=%ld)", cPenData, MAX_PENPLOTTER_PENS)); cPenData = MAX_PENPLOTTER_PENS; } PRK.pwKey = GetPenDataKey(wBuf, (WORD)(Index - PRKI_PENDATA1 + 1)); PRK.Size = (DWORD)sizeof(PENDATA) * (DWORD)cPenData; pPRK = &PRK; } else { pPRK = (PPLOTREGKEY)&PlotRegKey[Index]; } if (xSetPrinterData(hPrinter, pPRK->pwKey, REG_BINARY, pData, pPRK->Size) != NO_ERROR) { PLOTERR(("SetPlotRegData: SetPrinterData(%ls [%ld]) failed", pPRK->pwKey, pPRK->Size)); return(FALSE); } else { PLOTDBG(DBG_SETREGDATA, ("SAVE '%ws' registry data", pPRK->pwKey)); return(TRUE); } }
BOOL RotatePaper( PSIZEL pSize, PRECTL pImageArea, UINT RotateMode ) /*++ Routine Description: This function rotate a paper left 90 degree, right 90 degree or 180 degree depends on the RotateMode passed Arguments: pSize - Pointer to the size of the paper to be rotated pImageArea - Pointer to the RECTL of Imageable area RotateMode - Must be one of RM_L90, RM_R90, RM_180 Return Value: No return value, but the pSize, and pImageArea pointed to location will be updated. Author: 16-Dec-1993 Thu 09:18:33 created -by- Daniel Chou (danielc) Revision History: --*/ { SIZEL Size; RECTL Margin; // // To be sucessfully rotate the paper to the left 90 degree we must know // all four sides margin before we can do anything // Size = *pSize; Margin.left = pImageArea->left; Margin.top = pImageArea->top; Margin.right = Size.cx - pImageArea->right; Margin.bottom = Size.cy - pImageArea->bottom; PLOTASSERT(0, "RotatePaper: cx size too small (%ld)", (Size.cx - Margin.left - Margin.right) > 0, Size.cx); PLOTASSERT(0, "RotatePaper: cy size too small (%ld)", (Size.cy - Margin.top - Margin.bottom) > 0, Size.cy); PLOTDBG(DBG_ROTPAPER, ("RotatePaper(%ld) FROM (%ld x %ld), (%ld, %ld)-(%ld, %ld)", (LONG)RotateMode, pSize->cx, pSize->cy, pImageArea->left, pImageArea->top, pImageArea->right, pImageArea->bottom)); // // Now we can pick the right margin/corner for the rotation // // cx Rotate Left 90 Rotate Right 90 // +-------+ // | T | cy cy // | | +------------+ +------------+ // c| | | R | | L | // y| | c| | c| | // |L R| x| | x| | // | | |T B| |B T| // | | | | | | // | | | L | | R | // | B | +------------+ +------------+ // +-------+ // switch (RotateMode) { case RM_L90: pSize->cx = Size.cy; pSize->cy = Size.cx; pImageArea->left = Margin.top; pImageArea->top = Margin.right; pImageArea->right = Size.cy - Margin.bottom; pImageArea->bottom = Size.cx - Margin.left; break; case RM_R90: pSize->cx = Size.cy; pSize->cy = Size.cx; pImageArea->left = Margin.bottom; pImageArea->top = Margin.left; pImageArea->right = Size.cy - Margin.top; pImageArea->bottom = Size.cx - Margin.right; break; case RM_180: pImageArea->top = Margin.bottom; pImageArea->bottom = Size.cy - Margin.top; break; default: PLOTERR(("RotatePaper(%ld): Invalid RotateMode passed", RotateMode)); return(FALSE); } PLOTDBG(DBG_ROTPAPER, ("RotatePaper(%ld) - TO (%ld x %ld), (%ld, %ld)-(%ld, %ld)", (LONG)RotateMode, pSize->cx, pSize->cy, pImageArea->left, pImageArea->top, pImageArea->right, pImageArea->bottom)); return(TRUE); }
BOOL AddFormsToDataBase( PPRINTERINFO pPI, BOOL DeleteFirst ) /*++ Routine Description: This function add driver supports forms to the data base Arguments: pPI - Pointer to the PRINTERINFO Return Value: BOOLEAN Author: 09-Dec-1993 Thu 22:38:27 created 27-Apr-1994 Wed 19:18:58 updated Fixed bug# 13592 which printman/spooler did not call ptrprop first but docprop so let us into unknown form database state, Revision History: --*/ { WCHAR wName[CCHFORMNAME + 2]; BOOL bRet; LONG i; DWORD Type; Type = REG_SZ; if ((GetPrinterData(pPI->hPrinter, wszModel, &Type, (LPBYTE)wName, sizeof(wName), &i) == ERROR_SUCCESS) && (wcscmp(pPI->PlotDM.dm.dmDeviceName, wName))) { PLOTDBG(DBG_FORMS, ("Already added forms to the data base for %s", pPI->PlotDM.dm.dmDeviceName)); return(TRUE); } // // Find out if we have permission to do this // if (SetPrinterData(pPI->hPrinter, wszModel, REG_SZ, (LPBYTE)pPI->PlotDM.dm.dmDeviceName, (wcslen(pPI->PlotDM.dm.dmDeviceName) + 1) * sizeof(WCHAR)) == ERROR_SUCCESS) { PFORMSRC pFS; FORM_INFO_1 FI1; // // We have permission to update the registry so do it now // pPI->Flags |= PIF_UPDATE_PERMISSION; PLOTDBG(DBG_PERMISSION, ("!!! MODEL NAME: '%s' not Match, Re-installed Form Database", pPI->PlotDM.dm.dmDeviceName)); // // Add the driver supportes forms to the system spooler data base if // not yet done so // FI1.pName = wName; for (i = 0, pFS = (PFORMSRC)pPI->pPlotGPC->Forms.pData; i < (LONG)pPI->pPlotGPC->Forms.Count; i++, pFS++) { // // We will only add the non-roll paper forms // if (pFS->Size.cy) { str2Wstr(wName, CCHOF(wName), pFS->Name); // // Firstable we will delete the same name form in the data // base first, this will ensure we have our curent user defined // form can be installed // if (DeleteFirst) { DeleteForm(pPI->hPrinter, wName); } FI1.Size = pFS->Size; FI1.ImageableArea.left = pFS->Margin.left; FI1.ImageableArea.top = pFS->Margin.top; FI1.ImageableArea.right = FI1.Size.cx - pFS->Margin.right; FI1.ImageableArea.bottom = FI1.Size.cy - pFS->Margin.bottom; PLOTDBG(DBG_FORMS, ( "AddForm: %s-[%ld x %ld] (%ld, %ld)-(%ld, %ld)", FI1.pName, FI1.Size.cx, FI1.Size.cy, FI1.ImageableArea.left, FI1.ImageableArea.top, FI1.ImageableArea.right,FI1.ImageableArea.bottom)); FI1.Flags = FORM_PRINTER; if ((!AddForm(pPI->hPrinter, 1, (LPBYTE)&FI1)) && (GetLastError() != ERROR_FILE_EXISTS) && (GetLastError() != ERROR_ALREADY_EXISTS)) { bRet = FALSE; PLOTERR(("AddFormsToDataBase: AddForm(%s) failed, [%ld]", wName, GetLastError())); } } } return(TRUE); } else { pPI->Flags &= ~PIF_UPDATE_PERMISSION; PLOTDBG(DBG_PERMISSION, ("AddFormsToDataBase(): NO UPDATE PERMISSION")); return(FALSE); } }
SHORT GetDefaultPaper( PPAPERINFO pPaperInfo ) /*++ Routine Description: This function compute the default paper name, size. Arguments: pPaperInfo - Point to the paper info which will be fill by this function Return Value: It return a SHORT value which specified the standard paper index in as DMPAPER_xxx Author: 03-Dec-1993 Fri 13:13:42 created -by- Daniel Chou (danielc) Revision History: --*/ { SHORT dmPaperSize; pPaperInfo->ImageArea.left = pPaperInfo->ImageArea.top = 0; if (IsA4PaperDefault()) { dmPaperSize = (SHORT)DMPAPER_A4; pPaperInfo->Size.cx = pPaperInfo->ImageArea.right = DMTOSPL(A4_FORM_CX); pPaperInfo->Size.cy = pPaperInfo->ImageArea.bottom = DMTOSPL(A4_FORM_CY); wcscpy(pPaperInfo->Name, A4_FORM_NAME); PLOTDBG(DBG_DEFPAPER, ("Pick 'A4' paper as default")); } else { dmPaperSize = (SHORT)DMPAPER_LETTER; pPaperInfo->Size.cx = (LONG)_DefPlotDM.dm.dmPaperWidth; pPaperInfo->Size.cy = (LONG)_DefPlotDM.dm.dmPaperLength; dmPaperSize = (SHORT)DMPAPER_LETTER; pPaperInfo->Size.cx = pPaperInfo->ImageArea.right = DMTOSPL(_DefPlotDM.dm.dmPaperWidth); pPaperInfo->Size.cy = pPaperInfo->ImageArea.bottom = DMTOSPL(_DefPlotDM.dm.dmPaperLength); wcscpy(pPaperInfo->Name, _DefPlotDM.dm.dmFormName); PLOTDBG(DBG_DEFPAPER, ("Pick 'Letter' paper as default")); } PLOTDBG(DBG_DEFPAPER, ("SetDefaultPaper: '%ls' (%ld x %ld)", pPaperInfo->Name, pPaperInfo->Size.cx, pPaperInfo->Size.cy)); return(dmPaperSize); }
BOOL CloneBitBltSURFOBJ( PPDEV pPDev, SURFOBJ *psoDst, SURFOBJ *psoSrc, SURFOBJ *psoMask, XLATEOBJ *pxlo, PRECTL prclDst, PRECTL prclSrc, PRECTL prclPat, BRUSHOBJ *pbo, PCLONESO pCloneSO, DWORD RopBG, DWORD RopFG ) /*++ Routine Description: This function will clone the source/pattern and/or create a temp source buffer if we need one Arguments: pPDev - Pointer to our PDEV psoDst - Pointer to our surfae obj psoSrc - Pointer to source surfae obj psoMask - Pointer to the mask surface object if neeed to be used as pat pxlo - translate object from source to destination prclDst - Pointer to the destination rectangle area for the bitblt prclSrc - Pointer to the source rectangle area prclPat - pointer to the pattern rectangle area pbo - Pointer to the pointer of brush object pCloneSO - Pointer to the CLONSO[3] which stored the clone result RopBG - Background rop3 RopFG - Foreground rop3 Return Value: BOOLEAN Author: 24-Jan-1994 Mon 15:58:27 created Revision History: --*/ { DWORD Index; INT CompPat; BYTE Flags; // // Invert Rop3 if we are out of data range (128-255) and then invert // the final result (by inverting last Mix2 Rop2 code (0-15), all Rop3/Rop2 // codes are symmetric. // if ((Index = RopBG) >= 0x80) { Index ^= 0xFF; } Flags = GET_SDMIX_MIX2F(Rop3ToSDMix[Index]); if ((Index = RopFG) >= 0x80) { Index ^= 0xFF; } Flags |= GET_SDMIX_MIX2F(Rop3ToSDMix[Index]); // // Clone the PATTERN if necessary. // if ((ROP3_NEED_PAT(RopFG)) || (ROP3_NEED_PAT(RopBG))) { // // Only Clone the MASK/PATTERN if it is required // PLOTDBG(DBG_CLONESO, ("CloneBitBltSURFOBJ: NEED PATTERN ")); if (psoMask) { PLOTDBG(DBG_CLONESO, ("CloneBitBltSURFOBJ: Use psoMask as pattern")); if (!(pCloneSO[CSI_PAT].pso = CloneMaskSURFOBJ(pPDev, psoMask, &pCloneSO[CSI_PAT].hBmp, prclPat))) { PLOTERR(("CloneBitBltSURFOBJ:: CloneMaskSURFOBJ(psoPat) failed")); return(FALSE); } } else { // // Firs get the DEVBRUSH out. // if (!(CompPat = (INT)GetColor(pPDev, pbo, NULL, NULL, RopBG))) { PLOTERR(("CloneBitBltSURFOBJ:: GetColor for DEVBRUSH failed")); return(FALSE); } // // If we do not have a device compatible pattern or if we have to // do a SRC/PAT memory operation then we need to clone the pattern // if ((CompPat < 0) || (Flags & MIX2F_NEED_TMP)) { if (!(pCloneSO[CSI_PAT].pso = CloneBrushSURFOBJ(pPDev, psoDst, &pCloneSO[CSI_PAT].hBmp, pbo))) { PLOTERR(("CloneBitBltSURFOBJ:: CloneBrushSURFOBJ(psoPat) failed")); return(FALSE); } prclPat->left = prclPat->top = 0; prclPat->right = pCloneSO[CSI_PAT].pso->sizlBitmap.cx; prclPat->bottom = pCloneSO[CSI_PAT].pso->sizlBitmap.cy; } } } // // Determine if we need to clone the source // if ((ROP3_NEED_SRC(RopFG) || ROP3_NEED_SRC(RopBG))) { if (IsHTCompatibleSurfObj(pPDev, psoSrc, pxlo, (Flags & MIX2F_NEED_TMP) ? 0 : (ISHTF_ALTFMT | ISHTF_DSTPRIM_OK))) { PLOTDBG(DBG_CLONESO, ("CloneBitBltSURFOBJ:: Compatible HT Format, SRC=%ld, DST=%ld [ALT=%ld]", psoSrc->iBitmapFormat, ((PDRVHTINFO)pPDev->pvDrvHTData)->HTBmpFormat, ((PDRVHTINFO)pPDev->pvDrvHTData)->AltBmpFormat)); } else { PLOTDBG(DBG_CLONESO, ("CloneBitBltSURFOBJ:: CLONING SOURCE")); if (!(pCloneSO[CSI_SRC].pso = CloneSURFOBJToHT(pPDev, psoDst, psoSrc, pxlo, &pCloneSO[CSI_SRC].hBmp, prclDst, prclSrc))) { PLOTDBG(DBG_CLONESO, ("CloneBitBltSURFOBJ:: CLONE Source FAILED")); return(FALSE); } } } // // Create a TEMP SURFOBJ for SRC/PAT memory operation if it is required // if (Flags & MIX2F_NEED_TMP) { PLOTDBG(DBG_CLONESO, ("CloneBitbltSURFOBJ: CLONE SRC_TMP (%ld x %ld)", prclSrc->right - prclSrc->left, prclSrc->bottom - prclSrc->top)); if (!(pCloneSO[CSI_TMP].pso = CreateBitmapSURFOBJ(pPDev, &pCloneSO[CSI_TMP].hBmp, prclSrc->right - prclSrc->left, prclSrc->bottom - prclSrc->top, HTBMPFORMAT(pPDev), NULL))) { PLOTDBG(DBG_CLONESO, ("CloneBitBltSURFOBJ:: CLONE SRC_TMP FAILED")); return(FALSE); } } return(TRUE); }
VOID SetDefaultPLOTDM( HANDLE hPrinter, PPLOTGPC pPlotGPC, LPWSTR pwDeviceName, PPLOTDEVMODE pPlotDM, PFORMSIZE pCurForm ) /*++ Routine Description: This function set the default devmode based on the current pPlotGPC Arguments: hPrinter - Handle to the printer pPlotGPC - our loaded/verified GPC data. pwDeviceName - the device name passed in pPlotDM - Pointer to our ExtDevMode pCurForm - Pointer to the FORMSIZE data structure which will be updated if the pointer is not NULL, the final result of the form size/imagable area selected by the user will be written to here. the form name will be in pPlotDM->dmFormName. Return Value: VOID Author: 14-Dec-1993 Tue 20:21:48 updated -by- Daniel Chou (danielc) Update the dmScale based on maximum the device can support 06-Dec-1993 Mon 12:49:52 updated -by- Daniel Chou (danielc) make sure we turn off the DM_xxx bits if one of those is not valid or supported in current plotter 16-Nov-1993 Tue 13:49:27 created -by- Daniel Chou (danielc) Revision History: --*/ { WCHAR DeviceName[CCHDEVICENAME]; if (pwDeviceName) { _WCPYSTR(DeviceName, pwDeviceName, CCHDEVICENAME); // // Make sure the PlotGPC's device name is ssync with the pDeviceName // passed // WStr2Str(pPlotGPC->DeviceName, DeviceName); PLOTDBG(DBG_DEFDEVMODE, ("PlotGPC DeviceName=%hs\npwDeviceName=%ls", pPlotGPC->DeviceName, pwDeviceName)); } else { PLOTERR(("No DeviceName passed, using GPC's '%hs'", pPlotGPC->DeviceName)); str2Wstr(DeviceName, pPlotGPC->DeviceName); } // // Make a default copy first then copy device name down // CopyMemory(pPlotDM, &_DefPlotDM, sizeof(PLOTDEVMODE)); WCPYFIELDNAME(pPlotDM->dm.dmDeviceName, DeviceName); // // We must turn off the DM_xxx bits in dmFields if we do not support it, // look at default fields we copy down then update it // if (pPlotGPC->MaxScale) { if ((WORD)pPlotDM->dm.dmScale > pPlotGPC->MaxScale) { pPlotDM->dm.dmScale = (SHORT)pPlotGPC->MaxScale; } } else { pPlotDM->dm.dmFields &= ~DM_SCALE; } if (pPlotGPC->MaxCopies <= 1) { pPlotDM->dm.dmFields &= ~DM_COPIES; } if (!(pPlotGPC->MaxQuality)) { pPlotDM->dm.dmFields &= ~DM_PRINTQUALITY; } // // DEFAULT 50% quality for byte align plotter (DJ 600) to do ROP right // if (pPlotGPC->Flags & PLOTF_RASTERBYTEALIGN) { pPlotDM->dm.dmPrintQuality = DMRES_LOW; PLOTWARN(("SetDefaultPLOTDM: HACK Default Qaulity = DMRES_LOW")); } if (!(pPlotGPC->Flags & PLOTF_COLOR)) { if (pPlotGPC->Flags & PLOTF_RASTER) { pPlotDM->dm.dmFields &= ~DM_COLOR; pPlotDM->dm.dmColor = DMCOLOR_MONOCHROME; } else { PLOTASSERT(0, "SetDefaultPLOTDM: The Pen Ploter CANNOT be MONO.", (pPlotGPC->Flags & PLOTF_COLOR), 0); pPlotGPC->Flags |= PLOTF_COLOR; } } // // Set default form name based on the country // SetDefaultDMForm(pPlotDM, pCurForm); }
BOOL DoMix2( PPDEV pPDev, SURFOBJ *psoDst, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, PRECTL prclDst, PRECTL prclSrc, PPOINTL pptlSrcOrg, DWORD Mix2 ) /*++ Routine Description: This function is responsible for doing a device copy of a bitmap with/without tiling and activating the proper Rop2 Arguments: pPDev - Pointer to the PDEV psoDst - pointer to the destination surface object psoSrc - pointer to the source surface object pco - Pointer to the CLIPOBJ pxlo - the translate object from the source to the destination prclDst - the output destination rectangle area prclSrc - the source rectangle area pptlSrcOrg - brush origin for the source rectangle, if this is NULL then prclSrc will not have to be aligned on the destination Mix2 - a rop2 mode 0 - 0x0F Return Value: BOOLEAN Author: 08-Feb-1994 Tue 16:33:41 updated fixed ptlSrcOrg problem, we need to modulate with source size before it get used. 27-Jan-1994 Thu 23:45:46 updated Re-write so that it can handle the tiling more efficient. 13-Jan-1994 Sat 09:34:06 created Revision History: --*/ { RECTL rclSrc; RECTL rclDst; POINTL ptlSrcOrg; LONG cxSrc; LONG cySrc; DWORD OHTFlags = 0; BOOL MemMix2; // // The final ROP is either a ROP3 or a ROP4 (no mask) and it is always // a rop2 operation which deals with the source and destination // // First make it into a Rop3 representation of Rop2 (Mix2) // PLOTASSERT(1, "DoMix2: Passed INVALID psoSrc (%08lx) = STYPE_DEVICE", (psoSrc) && (psoSrc->iType != STYPE_DEVICE), psoSrc); PLOTASSERT(1, "DoMix2: Unexpected Mix2 = %u, SHOULD NOT BE HERE", (Mix2 != MIX2_0) && (Mix2 != MIX2_1) && (Mix2 != MIX2_D) && (Mix2 != MIX2_nD), Mix2); Mix2 &= 0x0F; Mix2 |= (DWORD)(Mix2 << 4); switch (Mix2) { case 0x00: // 0 case 0xFF: // 1 case 0x55: // ~D DoSpecialRop3(psoDst, pco, prclDst, Mix2); case 0xAA: // D return(TRUE); } if (MemMix2 = (BOOL)(psoDst->iType != STYPE_DEVICE)) { // // Now make it into Rop4 representation of Rop2 (Mix2) // Mix2 |= (Mix2 << 8); } else { if (!IsHTCompatibleSurfObj(pPDev, psoSrc, pxlo, ((pxlo) ? ISHTF_ALTFMT : 0) | ISHTF_HTXB | ISHTF_DSTPRIM_OK)) { PLOTERR(("DoMix2: The psoSrc is not HT compatible format (%08lx", psoSrc->iBitmapFormat)); return(FALSE); } } cxSrc = prclSrc->right - prclSrc->left; cySrc = prclSrc->bottom - prclSrc->top; if (pptlSrcOrg) { ptlSrcOrg = *pptlSrcOrg; if ((ptlSrcOrg.x = (LONG)(prclDst->left - ptlSrcOrg.x) % cxSrc) < 0) { ptlSrcOrg.x += cxSrc; } if ((ptlSrcOrg.y = (LONG)(prclDst->top - ptlSrcOrg.y) % cySrc) < 0) { ptlSrcOrg.y += cySrc; } PLOTDBG(DBG_DOMIX2, ("DoMix2: ORG ptlSrcOrg=(%ld, %ld) -> (%ld, %ld)", pptlSrcOrg->x, pptlSrcOrg->y, ptlSrcOrg.x, ptlSrcOrg.y)); } else { ptlSrcOrg.x = ptlSrcOrg.y = 0; PLOTDBG(DBG_DOMIX2, ("DoMix2: >>> DO NOT NEED TO ALIGN SRC on DEST <<<")); } rclSrc.top = prclSrc->top + ptlSrcOrg.y; rclSrc.bottom = prclSrc->bottom; rclDst.top = prclDst->top; rclDst.bottom = rclDst.top + (rclSrc.bottom - rclSrc.top); PLOTDBG(DBG_DOMIX2, ("DoMix2: SrcFormat=%ld, DstFormat=%ld %hs", psoSrc->iBitmapFormat, psoDst->iBitmapFormat, (MemMix2) ? "[MemMix2]" : "")); PLOTDBG(DBG_DOMIX2, ("DoMix2: ORG: Dst=(%ld, %ld)-(%ld,%ld), Src=(%ld, %ld)-(%ld, %ld)", prclDst->left, prclDst->top, prclDst->right, prclDst->bottom, prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom)); while (rclDst.top < prclDst->bottom) { // // check if the destination bottom is overhanging, clip it, // // NOTE: This could happen the first time. // if (rclDst.bottom > prclDst->bottom) { // // Clip the source/destination rectangle, because we may do // EngBitBlt() or OutputHTBitmap() // rclSrc.bottom -= (rclDst.bottom - prclDst->bottom); rclDst.bottom = prclDst->bottom; } rclSrc.left = prclSrc->left + ptlSrcOrg.x; rclSrc.right = prclSrc->right; rclDst.left = prclDst->left; rclDst.right = rclDst.left + (rclSrc.right - rclSrc.left); while (rclDst.left < prclDst->right) { // // check if the destination right edge is overhanging, clip it if // necessary. // // NOTE: This could happen the first time. // if (rclDst.right > prclDst->right) { // // Clip the source/destination rectangle, because we may do a // EngBitBlt() or OutputHTBitmap() // rclSrc.right -= (rclDst.right - prclDst->right); rclDst.right = prclDst->right; } PLOTDBG(DBG_DOMIX2, ("DoMix2: TILE: Dst=(%ld, %ld)-(%ld,%ld), Src=(%ld, %ld)-(%ld, %ld)", rclDst.left, rclDst.top, rclDst.right, rclDst.bottom, rclSrc.left, rclSrc.top, rclSrc.right, rclSrc.bottom)); if (MemMix2) { // // In the memory version we don't have to worry about PCO so // just call EngBitBlt to do the work. // if (!(EngBitBlt(psoDst, // psoDst psoSrc, // psoSrc NULL, // psoMask pco, // pco NULL, // pxlo &rclDst, // prclDst (PPOINTL)&rclSrc, // pptlSrc NULL, // pptlMask NULL, // pbo (PPOINTL)&ptlZeroOrigin, // pptlBrushOrg Mix2))) { PLOTERR(("DoMix2: EngBitBlt(MemMix2=%04lx) Failed!!!",Mix2)); return(FALSE); } } else { if (!OutputHTBitmap(pPDev, psoSrc, pco, (PPOINTL)&rclDst, &rclSrc, Mix2, &OHTFlags)) { PLOTERR(("DoMix2: OutputHTBitmap() Failed!!!")); return(FALSE); } } // // Reset <source left> to the original left margin and move the // destination right to the left for the next destination RECTL. // rclSrc.left = prclSrc->left; rclDst.left = rclDst.right; rclDst.right += cxSrc; } // // Reset <source top> to the original top margin and move the // destination bottom to the top, and set bottom for the next destination // RECTL. // rclSrc.top = prclSrc->top; rclDst.top = rclDst.bottom; rclDst.bottom += cySrc; } if (OHTFlags & OHTF_MASK) { OHTFlags |= OHTF_EXIT_TO_HPGL2; OutputHTBitmap(pPDev, psoSrc, NULL, NULL, NULL, 0xAA, &OHTFlags); } return(TRUE); }
DWORD MergePLOTDM( HANDLE hPrinter, PPLOTGPC pPlotGPC, PPLOTDEVMODE pPlotDMFrom, PPLOTDEVMODE pPlotDMTo, PFORMSIZE pCurForm ) /*++ Routine Description: This function merge and validate the pPlotDMTo from pPlotDMFrom. The PlotDMOut must valid Arguments: hPrinter - Handle to the printer to be checked pPlotGPC - The plotter's GPC data loaded from the file pPlotDMFrom - pointer to the input PLOTDEVMODE data structure, if can be NULL pPlotDMTo - Pointer to the output PLOTDEVMODE data structure, if pPlotDMFrom is NULL then a default PLOTDEVMODE is returned pCurForm - Pointer to the FORMSIZE data structure which will be updated if the pointer is not NULL, the final result of the form size/imagable area selected by the user will be written to here. the form name will be in pPlotDM->dmFormName. Return Value: the return value is a DWORD dmField error code which specified dmFields are invalid (DM_xxxxx in wingdi.h) if the return value has any DM_INV_xxx bits set then it should raised an error to the user. if return value is 0 then function sucessful Author: 25-Oct-1994 Tue 13:32:18 created -by- Daniel Chou (danielc) Revision History: --*/ { PLOTDEVMODE PlotDMIn; ENUMFORMPARAM EFP; DWORD dmErrFields = 0; SIZEL PaperSize; // // First: set the default PLOTDEVMODE for the output then from there // validate/settting from input devmode, if pwDeviceName passed as // NULL then it assume that pPlotDMTo alreay set and validated // // If we have invalid input devmode then this it is // if ((!pPlotDMFrom) || (!pPlotDMTo) || (!pPlotGPC)) { return(0); } // // Do some conversion here if necessary, first, copy the output one // CopyMemory(&PlotDMIn, pPlotDMTo, sizeof(PLOTDEVMODE)); ConvertDevmode((PDEVMODE) pPlotDMFrom, (PDEVMODE) &PlotDMIn); PLOTDBG(DBG_SHOWDEVMODE, ("--------------- Input DEVMODE Setting -------------------")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmDeviceName = %ls", (DWORD)PlotDMIn.dm.dmDeviceName)); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmSpecVersion = %04lx", (DWORD)PlotDMIn.dm.dmSpecVersion)); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmDriverVersion = %04lx", (DWORD)PlotDMIn.dm.dmDriverVersion)); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmSize = %0ld (%ld)", (DWORD)PlotDMIn.dm.dmSize, sizeof(DEVMODE))); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmDriverExtra = %ld (%ld)", (DWORD)PlotDMIn.dm.dmDriverExtra, PLOTDM_PRIV_SIZE)); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmFields = %08lx", (DWORD)PlotDMIn.dm.dmFields)); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmOrientation = %ld (%hs)", (DWORD)PlotDMIn.dm.dmOrientation, (PlotDMIn.dm.dmFields & DM_ORIENTATION) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmPaperSize = %ld (%hs)", (DWORD)PlotDMIn.dm.dmPaperSize, (PlotDMIn.dm.dmFields & DM_PAPERSIZE) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmPaperLength = %ld (%hs)", (DWORD)PlotDMIn.dm.dmPaperLength, (PlotDMIn.dm.dmFields & DM_PAPERLENGTH) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmPaperWidth = %ld (%hs)", (DWORD)PlotDMIn.dm.dmPaperWidth, (PlotDMIn.dm.dmFields & DM_PAPERWIDTH) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmScale = %ld (%hs)", (DWORD)PlotDMIn.dm.dmScale, (PlotDMIn.dm.dmFields & DM_SCALE) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmCopies = %ld (%hs)", (DWORD)PlotDMIn.dm.dmCopies, (PlotDMIn.dm.dmFields & DM_COPIES) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmPrintQuality = %ld (%hs)", (DWORD)PlotDMIn.dm.dmPrintQuality, (PlotDMIn.dm.dmFields & DM_PRINTQUALITY) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmColor = %ld (%hs)", (DWORD)PlotDMIn.dm.dmColor, (PlotDMIn.dm.dmFields & DM_COLOR) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: dmFormName = %ls (%hs)", (DWORD)PlotDMIn.dm.dmFormName, (PlotDMIn.dm.dmFields & DM_FORMNAME) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: Fill Truetype Font = %hs", (PlotDMIn.Flags & PDMF_FILL_TRUETYPE) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("ValidateSetPLOTDM: Plot On the Fly = %hs", (PlotDMIn.Flags & PDMF_PLOT_ON_THE_FLY) ? "ON" : "OFF")); PLOTDBG(DBG_SHOWDEVMODE, ("---------------------------------------------------------")); // // Statring checking the dmFields, *** REMEMBER: The orientation must // check before the checking the paper/form // if (PlotDMIn.dm.dmFields & DM_ORIENTATION) { switch (PlotDMIn.dm.dmOrientation) { case DMORIENT_PORTRAIT: case DMORIENT_LANDSCAPE: pPlotDMTo->dm.dmOrientation = PlotDMIn.dm.dmOrientation; pPlotDMTo->dm.dmFields |= DM_ORIENTATION; break; default: PLOTERR(("ValidatePLOTDM: Invalid dmOrientation = %ld", (LONG)PlotDMIn.dm.dmOrientation)); dmErrFields |= DM_ORIENTATION; break; } } // // Validate form name so we have correct data, assume error first // dmErrFields |= (DWORD)(PlotDMIn.dm.dmFields & DM_PAPER_FIELDS); if (((PlotDMIn.dm.dmFields & DM_PAPER_CUSTOM) == DM_PAPER_CUSTOM) && ((PlotDMIn.dm.dmPaperSize == DMPAPER_USER) || (PlotDMIn.dm.dmPaperSize == 0)) && (PaperSize.cx = DMTOSPL(PlotDMIn.dm.dmPaperWidth)) && (PaperSize.cy = DMTOSPL(PlotDMIn.dm.dmPaperLength)) && (PaperSize.cx >= MIN_SPL_FORM_CX) && (PaperSize.cy >= MIN_SPL_FORM_CY) && (((PaperSize.cx <= pPlotGPC->DeviceSize.cx) && (PaperSize.cy <= pPlotGPC->DeviceSize.cy)) || ((PaperSize.cy <= pPlotGPC->DeviceSize.cx) && (PaperSize.cx <= pPlotGPC->DeviceSize.cy)))) { // // First choice, this is what the caller wants, we need to validate // for this device, since the size may be larger then device can // handle // pPlotDMTo->dm.dmPaperWidth = PlotDMIn.dm.dmPaperWidth; pPlotDMTo->dm.dmPaperLength = PlotDMIn.dm.dmPaperLength; pPlotDMTo->dm.dmFields &= ~DM_PAPER_FIELDS; pPlotDMTo->dm.dmFields |= DM_PAPER_CUSTOM; pPlotDMTo->dm.dmPaperSize = DMPAPER_USER; pPlotDMTo->dm.dmFormName[0] = L'\0'; if (pCurForm) { // // This one is full imageable area as the widht/height // pCurForm->ImageArea.left = pCurForm->ImageArea.top = 0; pCurForm->Size.cx = pCurForm->ImageArea.right = PaperSize.cx; pCurForm->Size.cy = pCurForm->ImageArea.bottom = PaperSize.cy; } dmErrFields &= ~DM_PAPER_FIELDS; // Fine, no error PLOTDBG(DBG_CURFORM,("ValidateSetPLOTDM: FORM=USER <%ld> (%ld x %ld)", PlotDMIn.dm.dmPaperSize, PaperSize.cx, PaperSize.cy)); } else if ((PlotDMIn.dm.dmFields & (DM_PAPERSIZE | DM_FORMNAME)) && (EFP.pPlotDM = pPlotDMTo) && (EFP.pPlotGPC = pPlotGPC) && (PlotEnumForms(hPrinter, NULL, &EFP))) { FORM_INFO_1 *pFI1; SHORT PaperSize; BOOL Found = FALSE; // // Firstable check PaperSize index and if not found then check formname // if ((PlotDMIn.dm.dmFields & DM_PAPERSIZE) && ((PaperSize = PlotDMIn.dm.dmPaperSize) >= DMPAPER_FIRST) && (PaperSize <= (SHORT)EFP.Count) && (pFI1 = EFP.pFI1Base + (PaperSize - DMPAPER_FIRST)) && (pFI1->Flags & FI1F_VALID_SIZE)) { // // Whu..., this guy really pick a right index // Found = TRUE; PLOTDBG(DBG_CURFORM,("ValidateSetPLOTDM: Fount dmPaperSize=%ld", PlotDMIn.dm.dmPaperSize)); } else if (PlotDMIn.dm.dmFields & DM_FORMNAME) { // // Now go through all the formname trouble // pFI1 = EFP.pFI1Base; PaperSize = DMPAPER_FIRST; while (EFP.Count--) { if ((pFI1->Flags & FI1F_VALID_SIZE) && (!wcscmp(pFI1->pName, PlotDMIn.dm.dmFormName))) { PLOTDBG(DBG_CURFORM,("ValidateSetPLOTDM: Found dmFormName=%s", PlotDMIn.dm.dmFormName)); Found = TRUE; break; } ++PaperSize; ++pFI1; } } if (Found) { pPlotDMTo->dm.dmFields &= ~DM_PAPER_FIELDS; pPlotDMTo->dm.dmFields |= (DM_FORMNAME | DM_PAPERSIZE); pPlotDMTo->dm.dmPaperSize = PaperSize; pPlotDMTo->dm.dmPaperWidth = SPLTODM(pFI1->Size.cx); pPlotDMTo->dm.dmPaperLength = SPLTODM(pFI1->Size.cy); WCPYFIELDNAME(pPlotDMTo->dm.dmFormName, pFI1->pName); PLOTDBG(DBG_CURFORM,("FI1 [%ld]: (%ld x %ld), (%ld, %ld)-(%ld, %ld)", (LONG)pPlotDMTo->dm.dmPaperSize, pFI1->Size.cx, pFI1->Size.cy, pFI1->ImageableArea.left, pFI1->ImageableArea.top, pFI1->ImageableArea.right, pFI1->ImageableArea.bottom)); if (pCurForm) { pCurForm->Size = pFI1->Size; pCurForm->ImageArea = pFI1->ImageableArea; } dmErrFields &= ~DM_PAPER_FIELDS; // Fine, no error } // // Free up the memory used // LocalFree((HLOCAL)EFP.pFI1Base); } if ((PlotDMIn.dm.dmFields & DM_SCALE) && (pPlotGPC->MaxScale)) { if ((PlotDMIn.dm.dmScale > 0) && ((WORD)PlotDMIn.dm.dmScale <= pPlotGPC->MaxScale)) { pPlotDMTo->dm.dmScale = PlotDMIn.dm.dmScale; pPlotDMTo->dm.dmFields |= DM_SCALE; } else { PLOTERR(("ValidatePLOTDM: Invalid dmScale = %ld [%ld]", (LONG)PlotDMIn.dm.dmScale, (LONG)pPlotGPC->MaxScale)); dmErrFields |= DM_SCALE; } } if ((PlotDMIn.dm.dmFields & DM_COPIES) && (pPlotGPC->MaxCopies > 1)) { if ((PlotDMIn.dm.dmCopies > 0) && ((WORD)PlotDMIn.dm.dmCopies <= pPlotGPC->MaxCopies)) { pPlotDMTo->dm.dmCopies = PlotDMIn.dm.dmCopies; pPlotDMTo->dm.dmFields |= DM_COPIES; } else { PLOTERR(("ValidatePLOTDM: Invalid dmCopies = %ld [%ld]", (LONG)PlotDMIn.dm.dmCopies, (LONG)pPlotGPC->MaxCopies)); dmErrFields |= DM_COPIES; } } if (PlotDMIn.dm.dmFields & DM_PRINTQUALITY) { dmErrFields |= DM_PRINTQUALITY; // assume error, proven otherwise if (pPlotGPC->MaxQuality) { switch (PlotDMIn.dm.dmPrintQuality) { case DMRES_DRAFT: case DMRES_LOW: case DMRES_MEDIUM: case DMRES_HIGH: dmErrFields &= ~DM_PRINTQUALITY; pPlotDMTo->dm.dmPrintQuality = PlotDMIn.dm.dmPrintQuality; pPlotDMTo->dm.dmFields |= DM_PRINTQUALITY; break; } } if (dmErrFields & DM_PRINTQUALITY) { PLOTERR(("ValidatePLOTDM: Invalid dmPrintQuality = %ld [%ld]", (LONG)PlotDMIn.dm.dmPrintQuality, (LONG)pPlotGPC->MaxQuality)); } } if (PlotDMIn.dm.dmFields & DM_COLOR) { dmErrFields |= DM_COLOR; // assume error, proven otherwise if (pPlotGPC->Flags & PLOTF_COLOR) { switch (PlotDMIn.dm.dmColor) { case DMCOLOR_MONOCHROME: if (!(pPlotGPC->Flags & PLOTF_RASTER)) { PLOTERR(("ValidatePLOTDM: Cannot Set Pen Plotter to MONO")); break; } case DMCOLOR_COLOR: pPlotDMTo->dm.dmColor = PlotDMIn.dm.dmColor; pPlotDMTo->dm.dmFields |= DM_COLOR; dmErrFields &= ~DM_COLOR; break; } } else if (PlotDMIn.dm.dmColor == DMCOLOR_MONOCHROME) { dmErrFields &= ~DM_COLOR; } if (dmErrFields & DM_COLOR) { PLOTERR(("ValidatePLOTDM: Invalid dmColor = %ld [%hs]", (LONG)PlotDMIn.dm.dmColor, (pPlotGPC->Flags & PLOTF_COLOR) ? "COLOR" : "MONO")); } } // // Any other dmFields we just skip because we do not have that caps, now // check if they have correct EXTDEVMODE stuff // if ((PlotDMIn.dm.dmDriverExtra == PLOTDM_PRIV_SIZE) && (PlotDMIn.PrivID == PLOTDM_PRIV_ID) && (PlotDMIn.PrivVer == PLOTDM_PRIV_VER)) { pPlotDMTo->Flags = (DWORD)(PlotDMIn.Flags & PDMF_ALL_BITS); pPlotDMTo->ca = PlotDMIn.ca; if (pPlotGPC->Flags & PLOTF_RASTER) { pPlotDMTo->Flags |= PDMF_FILL_TRUETYPE; } else { // // Non raster device does not have plot on the fly mode // pPlotDMTo->Flags &= ~PDMF_PLOT_ON_THE_FLY; } if (!ValidateColorAdj(&(pPlotDMTo->ca))) { dmErrFields |= DM_INV_PLOTPRIVATE; PLOTERR(("ValidatePLOTDM: Invalid coloradjusment data")); } } return(dmErrFields); }
BOOL WINAPI DevQueryPrint( HANDLE hPrinter, DEVMODE *pDM, DWORD *pdwErrIDS ) /*++ Routine Description: This routine determines whether or not the driver can print the job described by pDevMode on the printer described by hPrinter. If if can, it puts zero into pdwErrIDS. If it cannot, it puts the resource id of the string describing why it could not. Arguments: hPrinter - Handle to the printer to be checked pDM - Point to the DEVMODE passed in pdwErrIDS - Point the the DWORD to received resource string ID number for the error. Return Value: This routine returns TRUE for success, FALSE for failure. when it return TRUE, the *pdwErrIDS determine if it can print or not, if *pdwErrIDS == 0, then it can print else it contains the string ID for the reason why it can not print. Author: 07-Dec-1993 Tue 00:50:32 created -by- Daniel Chou (danielc) 14-Jun-1994 Tue 22:43:36 updated -by- Daniel Chou (danielc) Make installed RollPaper always print if the size is reasonable Revision History: --*/ { PPRINTERINFO pPI = NULL; // // if it passed a NULL DEVMODE then we just honor it to said can print // if (!pDM) { PLOTWARN(("DevQueryPrint: No DEVMODE passed, CANNOT PRINT")); *pdwErrIDS = IDS_INV_DMSIZE; return(TRUE); } if (!(pPI = MapPrinter(hPrinter, (PPLOTDEVMODE)pDM, pdwErrIDS, MPF_DEVICEDATA))) { // // The MapPrinter will allocate memory, set default devmode, reading // and validating the GPC then update from current pritner registry, // PLOTRIP(("DevQueryPrint: MapPrinter() failed")); return(TRUE); } // // Assume this error // *pdwErrIDS = IDS_FORM_NOT_AVAI; if (pPI->dmErrBits & (USER_PAPER | DM_FORMNAME)) { // // We encounter some errors, and the form has been set to default // PLOTWARN(("DevQueryPrint: CAN'T PRINT, dmErrBits=%08lx (PAPER/FORM)", pPI->dmErrBits)); } else if ((pPI->PlotDM.dm.dmFields & DM_FORMNAME) && (wcscmp(pPI->CurPaper.Name, pPI->PlotDM.dm.dmFormName) == 0)) { // // We can print this form now // *pdwErrIDS = 0; PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: Match FormName=%s", pPI->PlotDM.dm.dmFormName)); } else if ((!pPI->CurPaper.Size.cy) || (((pPI->PlotDM.dm.dmFields & USER_PAPER) == USER_PAPER) && (pPI->PlotDM.dm.dmPaperSize == DMPAPER_USER)) || (pPI->PPData.Flags & PPF_SMALLER_FORM)) { LONG lTmp; SIZEL szl; BOOL VarLenPaper; // // 1. If we have ROLL PAPER Installed OR // 2. User Defined Paper Size // 3. User said OK to print smaller form then installed one // // THEN we want to see if it can fit into the device installed form // szl.cx = DMTOSPL(pPI->PlotDM.dm.dmPaperWidth); szl.cy = DMTOSPL(pPI->PlotDM.dm.dmPaperLength); if (VarLenPaper = (BOOL)!pPI->CurPaper.Size.cy) { pPI->CurPaper.Size.cy = pPI->pPlotGPC->DeviceSize.cy; } PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: CurPaper=%ldx%ld, Req=%ldx%ld, VarLen=%ld", pPI->CurPaper.Size.cx, pPI->CurPaper.Size.cy, szl.cx, szl.cy, VarLenPaper)); // // One of Following conditions met in that sequence then we can print // the form on loaded paper // // 1. Same size (PORTRAIT or LANDSCAPE) // 2. Larger Size (PORTRAIT or LANDSCAPE) AND // Not a variable length paper AND // PPF_SAMLLER_FORM flag set // if ((pPI->CurPaper.Size.cx < szl.cx) || (pPI->CurPaper.Size.cy < szl.cy)) { // // Swap this so we can do one easier comparsion later // SWAP(szl.cx, szl.cy, lTmp); } if ((pPI->CurPaper.Size.cx >= szl.cx) && (pPI->CurPaper.Size.cy >= szl.cy)) { if ((!VarLenPaper) && (!(pPI->PPData.Flags & PPF_SMALLER_FORM)) && ((pPI->CurPaper.Size.cx > szl.cx) || (pPI->CurPaper.Size.cy > szl.cy))) { PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: CAN'T PRINT: user DO NOT want print on larger paper")); } else { PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: Paper Size FITS in DEVICE, %ld x %ld", szl.cx, szl.cy)); *pdwErrIDS = 0; } } else { PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: CAN'T PRINT: Form Size too small")); } } PLOTDBG(DBG_DEVQPRINT, ("DevQueryPrint: %s PRINT %s", (*pdwErrIDS) ? "CAN'T" : "OK to", pPI->PlotDM.dm.dmFormName)); // // Unget the printer GPC mapping if we got one // UnMapPrinter(pPI); return(TRUE); }
LPWSTR GetPlotHelpFile( PPRINTERINFO pPI ) /*++ Routine Description: This function setup the directory path for the driver Help file Arguments: hPrinter - Handle to the printer Return Value: LPWSTR to the full path HelpFile, NULL if failed Author: 01-Nov-1995 Wed 18:43:40 created -by- Daniel Chou (danielc) Revision History: --*/ { PDRIVER_INFO_3 pDI3 = NULL; LPWSTR pHelpFile = NULL; WCHAR HelpFileName[MAX_HELPFILE_NAME]; DWORD cb; DWORD cb2; if (pPI->pHelpFile) { return(pPI->pHelpFile); } if ((!GetPrinterDriver(pPI->hPrinter, NULL, 3, NULL, 0, &cb)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (pDI3 = (PDRIVER_INFO_3)LocalAlloc(LMEM_FIXED, cb)) && (GetPrinterDriver(pPI->hPrinter, NULL, 3, (LPBYTE)pDI3, cb, &cb)) && (pDI3->pHelpFile) && (pHelpFile = (LPWSTR)LocalAlloc(LMEM_FIXED, cbWSTR(pDI3->pHelpFile)))) { wcscpy(pHelpFile, (LPWSTR)pDI3->pHelpFile); } else if ((cb2 = LoadString(hPlotUIModule, IDS_HELP_FILENAME, &HelpFileName[1], COUNT_ARRAY(HelpFileName) - 1)) && (cb2 = (cb2 + 1) * sizeof(WCHAR)) && (!GetPrinterDriverDirectory(NULL, NULL, 1, NULL, 0, &cb)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (pHelpFile = (LPWSTR)LocalAlloc(LMEM_FIXED, cb + cb2)) && (GetPrinterDriverDirectory(NULL, NULL, 1, (LPBYTE)pHelpFile, cb, &cb))) { HelpFileName[0] = L'\\'; wcscat(pHelpFile, HelpFileName); } else if (pHelpFile) { LocalFree(pHelpFile); pHelpFile = NULL; } if (pDI3) { LocalFree((HLOCAL)pDI3); } PLOTDBG(DBG_SHOW_HELP, ("GetlotHelpFile: '%ws", (pHelpFile) ? pHelpFile : L"Failed")); return(pPI->pHelpFile = pHelpFile); }
BOOL DrvStartDoc( SURFOBJ *pso, PWSTR pwDocName, DWORD JobId ) /*++ Routine Description: This function is called by start page, and is the second highest level initialization call. It initializes the beginning of a document, which is different from the beginning of a page, since multiple pages may exist in a document. Arguments: pso - Pointer to the SURFOBJ which belong to this driver pwDocName - Pointer to the document name to be started JobID - Job's ID Return Value: BOOL Author: 16-Nov-1993 Tue 01:55:15 updated -by- Daniel Chou (danielc) re-write 08-Feb-1994 Tue 13:51:59 updated -by- Daniel Chou (danielc) Move to StartPage for now Revision History: --*/ { PPDEV pPDev; if (!(pPDev = SURFOBJ_GETPDEV(pso))) { PLOTERR(("DrvStartDoc: invalid pPDev")); return(FALSE); } // // TODO we should review if we should do anything here... // PLOTDBG(DBG_STARTDOC,("DrvStartDoc: DocName = %s", pwDocName)); //TODO may need to resett stuff in drvstart page return(TRUE); }
BOOL SetPlotForm( PPLOTFORM pPlotForm, PPLOTGPC pPlotGPC, PPAPERINFO pCurPaper, PFORMSIZE pCurForm, PPLOTDEVMODE pPlotDM, PPPDATA pPPData ) /*++ Routine Description: This function computes the current FORM based on the printed margin. Auto rotation, landscape and other attributes are taken into account. The result is put into a PLOTFORM data structure located in our PDEV. This information is used to report data to GDI, as well as compute the HPGL2 parameters for sizing the target surface. Arguments: pPlotForm - Pointer to the PLOTFROM data structure which will be updated pPlotGPC - Pointer to the PLOTGPC data structure pCurPaper - Pointer to the PAPERINFO for the paper loaded pCurForm - Pointer to the FORMSIZE for the requested form pPlotDM - Pointer to the validated PLOTDEVMODE data structure pPPData - Pointer to the PPDATA structure Return Value: TRUE if sucessful, FALSE if failed Author: 29-Nov-1993 Mon 13:58:09 created 17-Dec-1993 Fri 23:09:38 updated Re-write so that we will look at CurPaper rather than pCurForm when setting the PSSize, p1/p2 stuff, it also rotate the pCurPaper if GPC/user said that the paper should loaded side way 20-Dec-1993 Mon 12:59:38 updated correct PFF_xxxx flag setting so we always rotate the bitmap to the left 90 degree 23-Dec-1993 Thu 20:35:57 updated Fixed roll paper clipping problem, change behavior, if we have roll paper installed then the it will make hard clip limit as big as user specified form size. 24-Dec-1993 Fri 12:20:02 updated Re-plot again, this is become really paint just try to understand what HP plotter design problems 06-Jan-1994 Thu 00:22:45 updated Update SPLTOPLOTUNITS() macro 07-Feb-1996 Wed 15:46:06 updated Change it so that it always using the current devmode form and then clip it to the device size. Revision History: This assumes that the user inserted the paper with width of the form first, LEGEND: + = Original paper corners * = Original plotter origin and its X/Y coordinate @ = the rotated origin using 'RO' command, intended to rotate the X/Y axis to the correct orientation for the window system # = Final plotter origin and its X/Y coordinate p1,p2 = final P1/P2 which will be used by the plotter driver cx,cy = Original paper width/height The following explaines how HPGL/2 loads the paper/form and assigns the default coordinate system to it, it also shows which way the paper is moving, the illustration to the right is when we need to rotate the printing direction and coordinate system when user selects the non-conforming X/Y coordinate system as opposed to the HPGL/2 default. ======================================================================= LENGTH >= WIDTH (CY >= CX) case ======================================================================= Portrait Paper Rotate Change Origin Default Left 90 Negative Y p2 cx cx p1 cx +---------+ +---------+ +---------+ | | | <------@| | | | | | X || | ^| | | ^| | | || | | || c| M || RO90 c| M || IP c| M || y| o || =====> y| o || ====> y| o || | v || | v Y|| | v Y|| | e X|| | e || | e || | | || | | || | | || | V || | V || | V || | Y || | V| | X || | <------*| | | | <------#| +---------+ +---------+ +---------+ p1 p2 | IP| | V Change Origin Negative X cx +---------+ | <------#| | Y || | | || c| M || y| o || | v X|| | e || | | || | V || | V| | | +---------+ ======================================================================= LENGTH < WIDTH (CY < CX) case ======================================================================= Landscape Rotate Left 90 Change Origin Paper Default Negative X cx p2 p2 cx cx +---------------+ +---------------+ +---------------+ | | | | | <--------#| |^ | | | | ^| | | Y || c|| M | c| M || c| M || y|| o | y| o || y| o || || v | RO90 | v X|| IP | v X|| ||Y e | =====> | e || ====> | e || || | | | | || | | || || X V | | V Y || | V V| |*--------> | | <--------@| | | +---------------+ +---------------+ +---------------+ p1 p1 | IP| | V Change Origin Negative X cx +---------------+ | | | | ^| c| M || y| o || | v Y|| | e || | | || | V X || | <--------#| +---------------+ --*/ { PLOTFORM PF; FORMSIZE DevForm; FORMSIZE ReqForm; RECTL rclDev; RECTL rclLog; SIZEL DeviceSize; LONG lTemp; BOOL DoRotate; PLOTDBG(DBG_PF, ("\n************* SetPlotForm *************\n")); // // We default using DeviceSize to check against the requested paper // DeviceSize = pPlotGPC->DeviceSize; rclDev = pPlotGPC->DeviceMargin; DoRotate = FALSE; // // Assume we using the current form from the devmode // DevForm = ReqForm = *pCurForm; PLOTDBG(DBG_PF, ("DeviceSize: %ld x %ld, L=%ld, T=%ld, R=%ld, B=%ld", DeviceSize.cx, DeviceSize.cy, rclDev.left, rclDev.top, rclDev.right, rclDev.bottom)); PLOTDBG(DBG_PF, ("ReqForm: <%s>", pPlotDM->dm.dmFormName, ReqForm.Size.cx, ReqForm.Size.cy)); PLOTDBG(DBG_PF, ("ReqForm: %ld x %ld, L=%ld, T=%ld, R=%ld, B=%ld [%ld x %ld]", ReqForm.Size.cx, ReqForm.Size.cy, ReqForm.ImageArea.left, ReqForm.ImageArea.top, ReqForm.ImageArea.right, ReqForm.ImageArea.bottom, ReqForm.ImageArea.right - ReqForm.ImageArea.left, ReqForm.ImageArea.bottom - ReqForm.ImageArea.top)); if (pCurPaper->Size.cy == 0) { // // ROLL PAPER CASE // // If we have roll paper installed, we must determine the projection // of the current form on the roll paper in order to get the size // to come out correctly. // DevForm.Size.cx = pCurPaper->Size.cx; DevForm.Size.cy = DeviceSize.cy; PLOTDBG(DBG_PF,(">>ROLL FEED<< RollPaper = %ld x %ld, <RESET rclDev to ALL ZEROs>", DevForm.Size.cx, DevForm.Size.cy)); } else if ((pPlotGPC->Flags & PLOTF_PAPERTRAY) && ((DevForm.Size.cx == DeviceSize.cx) || (DevForm.Size.cy == DeviceSize.cx))) { // // PAPER TRAY CASE: We need to make the DeviceSize equal to the DevForm // so that the margin will be correctly computed // DoRotate = (BOOL)(DevForm.Size.cx != DeviceSize.cx); PLOTDBG(DBG_PF,(">>PAPER TRAY<< Rotate Paper = %hs", (DoRotate) ? "YES" : "NO")); } else { PLOTASSERT(0, "SetPlotForm: Not supposed MANUAL feed the PAPER TRAY type PLOTTER", !(pPlotGPC->Flags & PLOTF_PAPERTRAY), pPlotGPC->Flags); PLOTDBG(DBG_PF,(">>MANUAL FEED<<")); // // MANUAL FEED CASE, this is the way paper is physically loaded, only // problem is if the paper is smaller than device can handle then we // really don't know where they inserted the paper. // DoRotate = (BOOL)(!(pPPData->Flags & PPF_MANUAL_FEED_CX)); PLOTDBG(DBG_PF,("The MANUAL FEED paper Inserted %hs side first.", (DoRotate) ? "Length CY" : "Width CX")); } if (DoRotate) { SWAP(DevForm.Size.cx, DevForm.Size.cy, lTemp); PLOTDBG(DBG_PF, ("### Rotated DevForm to %ld x %ld ###", DevForm.Size.cx, DevForm.Size.cy)); } // // Make sure largest requested form can be installed on the plotter // if (DevForm.Size.cx > DeviceSize.cx) { PLOTDBG(DBG_PF, ("WIDTH: DevForm (%ld) > DeviceSize (%ld). CORRECT IT", DevForm.Size.cx, DeviceSize.cx)); DevForm.Size.cx = DeviceSize.cx; } if (DevForm.Size.cy > DeviceSize.cy) { PLOTDBG(DBG_PF, ("HEIGHT: DevForm (%ld) > DeviceSize (%ld). CORRECT IT", DevForm.Size.cy, DeviceSize.cy)); DevForm.Size.cy = DeviceSize.cy; } // // Figure out how to fit this requested form onto loaded device form // DoRotate = FALSE; if ((DevForm.Size.cx >= ReqForm.Size.cx) && (DevForm.Size.cy >= ReqForm.Size.cy)) { // // Can print without doing any rotation, but check for paper saver, // the paper saver is only possible if: // // 1) Is a Roll paper, // 2) User approves // 3) ReqForm length > width // 4) DevForm width >= ReqForm length // if ((pCurPaper->Size.cy == 0) && (pPPData->Flags & PPF_AUTO_ROTATE) && (ReqForm.Size.cy > ReqForm.Size.cx) && (DevForm.Size.cx >= ReqForm.Size.cy)) { PLOTDBG(DBG_PF, ("ROLL PAPER SAVER: Doing AUTO_ROTATE")); DoRotate = !DoRotate; } } else if ((DevForm.Size.cx >= ReqForm.Size.cy) && (DevForm.Size.cy >= ReqForm.Size.cx)) { // // Can print but we have to rotate the form ourselves // PLOTDBG(DBG_PF, ("INTERNAL ROTATE to fit Requseted FROM into device")); DoRotate = !DoRotate; } else { // // CANNOT print the requested form, so clip the form requested // PLOTDBG(DBG_PF, (">>>>> ReqForm is TOO BIG to FIT, Need to CLIP IT <<<<<")); ReqForm.Size = DevForm.Size; } if (DoRotate) { DoRotate = (BOOL)(pPlotDM->dm.dmOrientation != DMORIENT_LANDSCAPE); // // If we need to rotate one more time back to the same position for // the logical paper size then we must rotate to the left first, this // is because ALL our ORIGIN x,y are either at the front of the plotter // or at the front panel side of the plotter // RotatePaper(&(ReqForm.Size), &(ReqForm.ImageArea), (DoRotate) ? RM_L90 : RM_R90); PLOTDBG(DBG_PF, ("INTERNAL Rotated ReqForm: %ld x %ld, L=%ld, T=%ld, R=%ld, B=%ld [%ld x %ld]", ReqForm.Size.cx, ReqForm.Size.cy, ReqForm.ImageArea.left, ReqForm.ImageArea.top, ReqForm.ImageArea.right, ReqForm.ImageArea.bottom, ReqForm.ImageArea.right - ReqForm.ImageArea.left, ReqForm.ImageArea.bottom - ReqForm.ImageArea.top)); } else { DoRotate = (BOOL)(pPlotDM->dm.dmOrientation == DMORIENT_LANDSCAPE); } // // Now the ReqForm is guaranteed to fit into the device paper. Find out how // it fits into the printable area and set the hardware margins appropriately. // DevForm.Size = ReqForm.Size; DevForm.ImageArea.left = rclDev.left; DevForm.ImageArea.top = rclDev.top; DevForm.ImageArea.right = DevForm.Size.cx - rclDev.right; DevForm.ImageArea.bottom = DevForm.Size.cy - rclDev.bottom; // // Intersect the requested form imageable area with the DevForm imageable area // IntersectRECTL(&(ReqForm.ImageArea), &(DevForm.ImageArea)); // // Now figure out the offset from the logical margin to the physical margin // rclLog.left = ReqForm.ImageArea.left - DevForm.ImageArea.left; rclLog.top = ReqForm.ImageArea.top - DevForm.ImageArea.top; rclLog.right = DevForm.ImageArea.right - ReqForm.ImageArea.right; rclLog.bottom = DevForm.ImageArea.bottom - ReqForm.ImageArea.bottom; // // Rotate the requested form if necessary // if (DoRotate) { RotatePaper(&(ReqForm.Size), &(ReqForm.ImageArea), RM_R90); // // Now we can pick the right margin/corner for the rotation // // cx Rotate Left 90 Rotate Right 90 // +-------+ // | T | cy cy // | | +------------+ +------------+ // c| | | R | | L | // y| | c| | c| | // |L R| x| | x| | // | | |T B| |B T| // | | | | | | // | | | L | | R | // | B | +------------+ +------------+ // +-------+ // PLOTDBG(DBG_PF, ("ROTATED RIGHT ReqForm: %ld x %ld, L=%ld, T=%ld, R=%ld, B=%ld [%ld x %ld]", ReqForm.Size.cx, ReqForm.Size.cy, ReqForm.ImageArea.left, ReqForm.ImageArea.top, ReqForm.ImageArea.right, ReqForm.ImageArea.bottom, ReqForm.ImageArea.right - ReqForm.ImageArea.left, ReqForm.ImageArea.bottom - ReqForm.ImageArea.top)); } PLOTDBG(DBG_PF, ("FINAL DevForm: %ld x %ld, L=%ld, T=%ld, R=%ld, B=%ld [%ld x %ld]", DevForm.Size.cx, DevForm.Size.cy, DevForm.ImageArea.left, DevForm.ImageArea.top, DevForm.ImageArea.right, DevForm.ImageArea.bottom, DevForm.ImageArea.right - DevForm.ImageArea.left, DevForm.ImageArea.bottom - DevForm.ImageArea.top)); PLOTDBG(DBG_PF, ("FINAL ReqForm: %ld x %ld, L=%ld, T=%ld, R=%ld, B=%ld [%ld x %ld]", ReqForm.Size.cx, ReqForm.Size.cy, ReqForm.ImageArea.left, ReqForm.ImageArea.top, ReqForm.ImageArea.right, ReqForm.ImageArea.bottom, ReqForm.ImageArea.right - ReqForm.ImageArea.left, ReqForm.ImageArea.bottom - ReqForm.ImageArea.top)); PLOTDBG(DBG_PF, ("rclLog: L=%ld, T=%ld, R=%ld, B=%ld", rclLog.left, rclLog.top, rclLog.right, rclLog.bottom)); // // Set fields in PLOTFORM // PF.Flags = 0; PF.BmpRotMode = BMP_ROT_NONE; PF.NotUsed = 0; PF.PlotSize.cx = DevForm.ImageArea.right - DevForm.ImageArea.left; PF.PlotSize.cy = DevForm.ImageArea.bottom - DevForm.ImageArea.top; PF.PhyOrg.x = ReqForm.ImageArea.left; PF.PhyOrg.y = ReqForm.ImageArea.top; PF.LogSize = ReqForm.Size; PF.LogExt.cx = ReqForm.ImageArea.right - ReqForm.ImageArea.left; PF.LogExt.cy = ReqForm.ImageArea.bottom - ReqForm.ImageArea.top; PF.BmpOffset.x = rclLog.left; PF.BmpOffset.y = rclLog.top; if (PF.PlotSize.cy >= PF.PlotSize.cx) { PLOTDBG(DBG_FORMSIZE,(">>>>> Plot SIze: CY >= CX (%ld: VERTICAL%hs) <<<<<", (DoRotate) ? 1 : 2, (DoRotate) ? " + ROTATE" : "")); // // The Standard HPGL/2 coordinate Y direction in in reverse, the scale // is from Max Y to 0. // if (DoRotate) { // // Portrait Paper Scale Coord X // Default Negative X // // p2 cx cx // +---------+ +---------+ // | | | <------#| // | | | Y || // | | ^| | | || // c| M || c| M || // y| o || ====> y| o || // | v || | v X|| // | e X|| | e || // | | || | | || // | V || | V || // | Y || | V| // | <------*| | | // +---------+ +---------+ // p1 // PF.Flags |= PFF_FLIP_X_COORD; PF.BmpRotMode = BMP_ROT_RIGHT_90; PF.LogOrg.x = rclLog.top; PF.LogOrg.y = rclLog.left; } else { // // Portrait Paper Rotate Scale Coord Y // Default Left 90 Negative Y // // p2 cx cx p1 cx // +---------+ +---------+ +---------+ // | | | <------@| | | // | | | X || | ^| // | | ^| | | || | | || // c| M || RO90 c| M || c| M || // y| o || =====> y| o || ====> y| o || // | v || | v Y|| | v Y|| // | e X|| | e || | e || // | | || | | || | | || // | V || | V || | V || // | Y || | V| | X || // | <------*| | | | <------#| // +---------+ +---------+ +---------+ // p1 p2 // PF.Flags |= (PFF_ROT_COORD_L90 | PFF_FLIP_Y_COORD); PF.LogOrg.x = rclLog.left; PF.LogOrg.y = rclLog.bottom; } } else { PLOTDBG(DBG_FORMSIZE,(">>>>> SetPlotForm: CY < CX (%ld: HORIZONTAL%hs) <<<<<", (DoRotate) ? 3 : 4, (DoRotate) ? " + ROTATE" : "")); // // The Standard HPGL/2 coordinate X direction in in reverse, the scale // is from Max X to 0 // if (DoRotate) { // // DoRotate Rotate Left 90 Scale Coord X // Paper Default Negative X // // cx p2 p2 cx cx // +---------------+ +---------------+ +---------------+ // | | | | | <--------#| // |^ | | | | ^| | | Y || // c|| M | c| M || c| M || // y|| o | y| o || y| o || // || v | RO90 | v X|| | v X|| // ||Y e |=====> | e || ==> | e || // || | | | | || | | || // || X V | | V Y || | V V| // |*--------> | | <--------@| | | // +---------------+ +---------------+ +---------------+ // p1 p1 // PF.Flags |= (PFF_ROT_COORD_L90 | PFF_FLIP_X_COORD); PF.BmpRotMode = BMP_ROT_RIGHT_90; PF.LogOrg.x = rclLog.top; PF.LogOrg.y = rclLog.left; } else { // // DoRotate Scale Coord X // Paper Default Negative X // // cx p2 cx // +----------------+ +-----------------+ // | | | | // |^ | | | | ^| // c|| M | c| M || // y|| o | y| o || // || v | ====> | v Y|| // ||Y e | | e || // || | | | | || // || X V | | V X || // |*--------> | | <--------#| // +----------------+ +-----------------+ // p1 // PF.Flags |= PFF_FLIP_X_COORD; PF.LogOrg.x = rclLog.right; PF.LogOrg.y = rclLog.top; } } PLOTDBG(DBG_PF, ("FINAL LogOrg: (%ld, %ld), PhyOrg=(%ld, %ld)", PF.LogOrg.x, PF.LogOrg.y, PF.PhyOrg.x, PF.PhyOrg.y)); // // Save result and output some information // *pPlotForm = PF; PLOTDBG(DBG_PLOTFORM,("******************************************************")); PLOTDBG(DBG_PLOTFORM,("******* SetPlotForm: ****** %hs --> %hs ******\n", (pPlotDM->dm.dmOrientation == DMORIENT_LANDSCAPE) ? "LANDSCAPE" : "PORTRAIT", (DoRotate) ? "LANDSCAPE" : "PORTRAIT")); PLOTDBG(DBG_PLOTFORM,(" Flags =%hs%hs%hs", (PF.Flags & PFF_ROT_COORD_L90) ? " <ROT_COORD_L90> " : "", (PF.Flags & PFF_FLIP_X_COORD) ? " <FLIP_X_COORD> " : "", (PF.Flags & PFF_FLIP_Y_COORD) ? " <FLIP_Y_COORD> " : "")); PLOTDBG(DBG_PLOTFORM,(" BmpRotMode = %hs", pBmpRotMode[PF.BmpRotMode])); PLOTDBG(DBG_PLOTFORM,(" PlotSize = (%7ld x%7ld) [%5ld x%6ld]", PF.PlotSize.cx, PF.PlotSize.cy, SPLTOPLOTUNITS(pPlotGPC, PF.PlotSize.cx), SPLTOPLOTUNITS(pPlotGPC, PF.PlotSize.cy))); PLOTDBG(DBG_PLOTFORM,("PhyOrg/Offset = (%7ld,%8ld) [%5ld,%7ld] ", PF.PhyOrg.x, PF.PhyOrg.y, SPLTOPLOTUNITS(pPlotGPC, PF.PhyOrg.x), SPLTOPLOTUNITS(pPlotGPC, PF.PhyOrg.y))); PLOTDBG(DBG_PLOTFORM,(" LogSize = (%7ld x%7ld) [%5ld x%6ld]", PF.LogSize.cx, PF.LogSize.cy, SPLTOPLOTUNITS(pPlotGPC, PF.LogSize.cx), SPLTOPLOTUNITS(pPlotGPC, PF.LogSize.cy))); PLOTDBG(DBG_PLOTFORM,(" LogOrg/p1 = (%7ld,%8ld) [%5ld,%7ld]", PF.LogOrg.x, PF.LogOrg.y, SPLTOPLOTUNITS(pPlotGPC, PF.LogOrg.x), SPLTOPLOTUNITS(pPlotGPC, PF.LogOrg.y))); PLOTDBG(DBG_PLOTFORM,(" LogExt = (%7ld,%8ld) [%5ld,%7ld]\n", PF.LogExt.cx, PF.LogExt.cy, SPLTOPLOTUNITS(pPlotGPC, PF.LogExt.cx), SPLTOPLOTUNITS(pPlotGPC, PF.LogExt.cy))); PLOTDBG(DBG_PLOTFORM,(" BmpOffset = (%7ld,%8ld) [%5ld,%7ld]", PF.BmpOffset.x, PF.BmpOffset.y, SPLTOPLOTUNITS(pPlotGPC, PF.BmpOffset.x), SPLTOPLOTUNITS(pPlotGPC, PF.BmpOffset.y))); PLOTDBG(DBG_PLOTFORM, ("Commands=PS%ld,%ld;%hsIP%ld,%ld,%ld,%ld;SC%ld,%ld,%ld,%ld\n", SPLTOPLOTUNITS(pPlotGPC, PF.PlotSize.cy), SPLTOPLOTUNITS(pPlotGPC, PF.PlotSize.cx), (PF.Flags & PFF_ROT_COORD_L90) ? "RO90;" : "", SPLTOPLOTUNITS(pPlotGPC, PF.LogOrg.x), SPLTOPLOTUNITS(pPlotGPC, PF.LogOrg.y), SPLTOPLOTUNITS(pPlotGPC, (PF.LogOrg.x + PF.LogExt.cx)) - 1, SPLTOPLOTUNITS(pPlotGPC, (PF.LogOrg.y + PF.LogExt.cy)) - 1, (PF.Flags & PFF_FLIP_X_COORD) ? SPLTOPLOTUNITS(pPlotGPC, PF.LogExt.cx) - 1 : 0, (PF.Flags & PFF_FLIP_X_COORD) ? 0 : SPLTOPLOTUNITS(pPlotGPC, PF.LogExt.cx) - 1, (PF.Flags & PFF_FLIP_Y_COORD) ? SPLTOPLOTUNITS(pPlotGPC, PF.LogExt.cy) - 1 : 0, (PF.Flags & PFF_FLIP_Y_COORD) ? 0 : SPLTOPLOTUNITS(pPlotGPC, PF.LogExt.cy) - 1)); return(TRUE); }
LPWSTR GetPlotHelpFile( PPRINTERINFO pPI ) /*++ Routine Description: This function setup the directory path for the driver Help file Arguments: hPrinter - Handle to the printer Return Value: LPWSTR to the full path HelpFile, NULL if failed Development History: 01-Nov-1995 Wed 18:43:40 created Revision History: --*/ { PDRIVER_INFO_3 pDI3 = NULL; LPWSTR pHelpFile = NULL; WCHAR HelpFileName[MAX_HELPFILE_NAME]; DWORD cb; DWORD cb2; DWORD dwMemAllocSize = 0; HRESULT hr = E_FAIL; if (pPI->pHelpFile) { return(pPI->pHelpFile); } if ((!GetPrinterDriver(pPI->hPrinter, NULL, 3, NULL, 0, &cb)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (pDI3 = (PDRIVER_INFO_3)LocalAlloc(LMEM_FIXED, cb)) && (GetPrinterDriver(pPI->hPrinter, NULL, 3, (LPBYTE)pDI3, cb, &cb)) && (pDI3->pHelpFile) && (SUCCEEDED(DWordAdd((DWORD)wcslen(pDI3->pHelpFile), 1, &dwMemAllocSize))) && (SUCCEEDED(DWordMult(dwMemAllocSize, sizeof(WCHAR), &dwMemAllocSize))) && (pHelpFile = (LPWSTR)LocalAlloc(LMEM_FIXED, dwMemAllocSize))) { hr = StringCchCopyW(pHelpFile, dwMemAllocSize / sizeof(WCHAR), (LPWSTR)pDI3->pHelpFile); } else if ((cb2 = LoadString(hPlotUIModule, IDS_HELP_FILENAME, &HelpFileName[1], COUNT_ARRAY(HelpFileName) - 1)) && (SUCCEEDED(DWordAdd(cb2, 1, &cb2))) && (SUCCEEDED(DWordMult(cb2, sizeof(WCHAR), &cb2))) && (!GetPrinterDriverDirectory(NULL, NULL, 1, NULL, 0, &cb)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (SUCCEEDED(DWordAdd(cb, cb2, &dwMemAllocSize))) && (pHelpFile = (LPWSTR)LocalAlloc(LMEM_FIXED, dwMemAllocSize)) && (GetPrinterDriverDirectory(NULL, NULL, 1, (LPBYTE)pHelpFile, cb, &cb))) { HelpFileName[0] = L'\\'; hr = StringCchCatW(pHelpFile, dwMemAllocSize / sizeof(WCHAR), HelpFileName); } if (pDI3) { LocalFree((HLOCAL)pDI3); pDI3 = NULL; } if (pHelpFile && !SUCCEEDED(hr)) { LocalFree(pHelpFile); pHelpFile = NULL; } PLOTDBG(DBG_SHOW_HELP, ("GetlotHelpFile: '%ws", (pHelpFile) ? pHelpFile : L"Failed")); return(pPI->pHelpFile = pHelpFile); }
LONG GetColor( PPDEV pPDev, BRUSHOBJ *pbo, LPDWORD pColorFG, PDEVBRUSH *ppDevBrush, ROP4 Rop4 ) /*++ Routine Description: Realize the brush color and return the color Arguments: pPDev - Pointer to our DEV pbo - Engine brush object pColorFG - pointer to the ULONG to received forground color, NULL if not needed ppDevBrush - Pointer to the location to received brush, NULL if not needed Rop4 - Rop4 to be used, this function looks at this in order to determine if the brush can be used with the HPGL2 cmds or that the brush will have to be simulated. Return Value: LONG > 0 The Brush is compatible with device format (Fill command) = 0 Failed < 0 The brush must send to device via a bitblt Author: 13-Jan-1994 Thu 20:18:49 created 15-Jan-1994 Sat 06:58:56 updated Change parameters and return value 16-May-1994 Mon 15:59:45 updated Adding PDEV Revision History: --*/ { PDEVBRUSH pDevBrush = NULL; LONG RetVal = 1; DWORD SolidColor = 0xFFFFFF; DWORD RopBG; DWORD RopFG; // // Get the ROP for the foureground and background. This information is // used to determine if the brush has to be simulated, or can be // used with selectable pens in the target device. RopBG = ROP4_BG_ROP(Rop4); RopFG = ROP4_FG_ROP(Rop4); // // Get the current color and select the appropriate pen, this should // ONLY be a solid color as we don't support stroking with arbitrary // brushes. // if (pbo) { // // get the brush realization, and select a pen. // If the BRUSHOBJ's iSolidColor field is a valid color, then // we must do a solid fill with that pen. Otherwise, we must // check the realization of the brush to do a pattern fill. // // To return a Fillable pattern by DoFill, one of the following conditions // must be true and in this sequence // // 1. SOLID COLOR // 2. STANDARD PATTERN // 3. Device compatible bitmap // if ((SolidColor = (DWORD)pbo->iSolidColor) == CLR_INVALID) { PLOTDBG(DBG_GETCLR, ("iSolodColor == CLR_INVALID, pBrush=%08lx", pbo->pvRbrush)); // // This is a pattern brush, but we will just use its // foreground color. // if ((pDevBrush = (PDEVBRUSH)pbo->pvRbrush) || (pDevBrush = BRUSHOBJ_pvGetRbrush(pbo))) { // // Grab the foreground color and use it. // SolidColor = pDevBrush->ColorFG; if ((pDevBrush->PatIndex < HS_DDI_MAX) || (pDevBrush->pbgr24)) { ; } else { PLOTDBG(DBG_GETCLR, ("GETColor: NOT DEVICE_PAT")); RetVal = -1; } } else { RetVal = 0; PLOTDBG(DBG_GETCLR, ("GetColor(): couldn't realize brush!")); } } else { PLOTDBG(DBG_GETCLR, ("GETColor: is a SOLID COLOR=%08lx", pbo->iSolidColor)); } } else if ((RopFG == 0x00) || (RopBG == 0x00)) { if (IS_RASTER(pPDev)) { SolidColor = 0x0; } else { // // If we are not a raster device (which supports overprint) // match the best non-white pen, in order to fill with. // SolidColor = (DWORD)BestMatchNonWhitePen(pPDev, 0, 0, 0); PLOTDBG(DBG_GETCLR, ("GETColor: pbo=NULL, BLACK Pen Idx=%ld", SolidColor)); } } if ((!IS_RASTER(pPDev)) && (SolidColor == 0x00FFFFFF)) { SolidColor = WHITE_INDEX; PLOTDBG(DBG_GETCLR, ("GETColor: Pen plotter using WHITE COLOR Idx=%ld", SolidColor)); } if (pColorFG) { *pColorFG = SolidColor; } if (ppDevBrush) { *ppDevBrush = pDevBrush; } return(RetVal); }