Exemple #1
0
VOID
PsSelectManualFeed(
    PDEVDATA    pdev,
    BOOL        bManual
)

/*++

Routine Description:

    Enable or disable manual feed feature on the printer.

Arguments:

    bManual     TRUE to enable manual feed and FALSE to disable it

Return Value:

    NONE

--*/

{
    PSTR    pstr;

    // Check if the manual feed feature is already
    // in the requested state.

    if (bManual != ((pdev->dwFlags & PDEV_MANUALFEED) != 0)) {

        // Generate PostScript to send to the printer
        // and enclosed within a stopped context.

        DscBeginFeature(pdev, "ManualFeed ");
        psprintf(pdev, "%s\n", bManual ? "True" : "False");

        if ((pstr = PpdFindManualFeedCode(pdev->hppd, bManual)) != NULL) {

            psputs(pdev, pstr);
        }

        DscEndFeature(pdev);

        // Set or clear the manual feed flag in DEVDATA

        if (bManual)
            pdev->dwFlags |= PDEV_MANUALFEED;
        else
            pdev->dwFlags &= ~PDEV_MANUALFEED;
    }
}
Exemple #2
0
VOID
SetTimeoutValues(
    PDEVDATA    pdev
)

/*++

Routine Description:

    Output code to printer to set job and wait timeout values

Arguments:

    pdev        Pointer to DEVDATA structure

Return Value:

    NONE

--*/

{
    psprintf(pdev, "[{%d\n", pdev->pPrinterData->dwJobTimeout);
    psputs(pdev,
           "/languagelevel where{pop languagelevel 2 ge}{false}ifelse\n"
           "{1 dict dup/JobTimeout 4 -1 roll put setuserparams}\n"
           "{statusdict/setjobtimeout get exec}ifelse\n"
           "}stopped cleartomark\n");

    psprintf(pdev, "[{%d\n", pdev->pPrinterData->dwWaitTimeout);
    psputs(pdev,
           "/languagelevel where{pop languagelevel 2 ge}{false}ifelse\n"
           "{1 dict dup/WaitTimeout 4 -1 roll put setuserparams}\n"
           "{statusdict/waittimeout 3 -1 roll put}ifelse\n"
           "}stopped cleartomark\n");
}
Exemple #3
0
VOID
SetResolution(
    PDEVDATA    pdev,
    DWORD       res,
    WORD        restype)

/*++

Routine Description:

    Generate commands to set printer resolution.

Arguments:

    pdev    pointer to device data
    res     desired resolution
    bPJL    TRUE this is called at the beginning of a job
            FALSE if this called during the setup section

Return Value:

    NONE

--*/

{
    HPPD        hppd = pdev->hppd;
    PRESOPTION  pResOption;

    // We only need to do something when the requested
    // resolution type matches what the printer can do

    if (restype != hppd->wResType)
        return;

    // Check if the desired resolution is supported

    pResOption = PpdFindResolution(hppd, res);

    // Ignore if the desired resolution is not found

    if (pResOption == NULL) {

        DBGMSG1(DBG_LEVEL_TERSE,
                "No invocation string for resolution option: %d.\n", res);
        return;
    }

    switch (restype) {

    case RESTYPE_NORMAL:        // Use normal PS code

        if (pResOption->pInvocation == NULL) {

            DBGMSG(DBG_LEVEL_ERROR, "Failed to set resolution.");
        } else {

            DscBeginFeature(pdev, "Resolution ");
            psprintf(pdev, "%d\n", res);
            psputs(pdev, pResOption->pInvocation);
            DscEndFeature(pdev);
        }
        break;

    case RESTYPE_JCL:           // Use JCL code

        if (! PpdSupportsProtocol(hppd,PROTOCOL_PJL) ||
                pResOption->pJclCode == NULL)
        {
            DBGMSG(DBG_LEVEL_ERROR,
                   "Cannot set resolution using PJL commands.\n");
        } else {

            psputs(pdev, pResOption->pJclCode);
        }
        break;

    case RESTYPE_EXITSERVER:    // Use exitserver code

        if (pResOption->pSetResCode == NULL) {

            DBGMSG(DBG_LEVEL_ERROR, "Failed to set resolution.");
        } else {

            PSTR    password = hppd->pPassword ? hppd->pPassword : "******";

            psputs(pdev, "%%BeginExitServer: ");
            psputs(pdev, password);
            psprintf(pdev, "\n%%%%Resolution: %d\n", res);
            psputs(pdev, password);
            psputs(pdev, "\n");
            psputs(pdev, pResOption->pSetResCode);
            psputs(pdev, "\n%%EndExitServer\n");
        }
        break;
    }
}
Exemple #4
0
VOID
PsSelectCustomPageSize(
    PDEVDATA    pdev
)

/*++

Routine Description:

    Generate PostScript code to select custom page size
    on the printer.

Arguments:

    pdev    Pointer to DEVDATA structure

Return Value:

    NONE

--*/

{
    PSREAL  params[MAXPCP];
    INT     index;
    HPPD    hppd = pdev->hppd;
    PSREAL  xlen, ylen;

    // Sanity check: if no custom page size invocation is provided,
    // simply return with emitting anything.

    if (hppd->pCustomSizeCode == NULL) {

        DBGMSG(DBG_LEVEL_WARNING,
               "No invocation string for custom page size.\n");
        return;
    }

    // Generate parameters for custom page size invocation
    // Sort them according to the order specified in PPD file

    for (index=0; index < MAXPCP; index++)
        params[index] = 0;

    // Figure out size of the physical page along x- and y-axis
    //
    // Undo the effect of AdjustForLandscape here:
    // in landscape mode, CurForm.PaperSize.width and
    // and CurForm.PaperSize.height were swapped.

    if (pdev->CurForm.bLandscape) {

        xlen = pdev->CurForm.PaperSize.height;
        ylen = pdev->CurForm.PaperSize.width;
    } else {

        xlen = pdev->CurForm.PaperSize.width;
        ylen = pdev->CurForm.PaperSize.height;
    }

    if (! hppd->bCutSheet) {

        PSREAL  maxWidth, maxHeight, tmpPsreal;

        // For roll-fed devices, choose orientation 0 or 1
        // depending on whether width is bigger than height

        maxWidth = hppd->maxMediaWidth -
                   hppd->customParam[PCP_WIDTHOFFSET].minVal;

        maxHeight = hppd->maxMediaHeight -
                    hppd->customParam[PCP_HEIGHTOFFSET].minVal;

        if (xlen <= ylen && ylen <= maxWidth && xlen <= maxHeight) {

            // Use orientation 0: ylen is used as width parameter
            // and xlen is used as height parameter

            if (hppd->customParam[PCP_ORIENTATION].minVal > 0) {

                DBGMSG(DBG_LEVEL_ERROR,
                       "Device does not support orientation 0.\n");
            }

            tmpPsreal = xlen;
            xlen = ylen;
            ylen = tmpPsreal;

        } else {

            // Use orientation 1

            if (hppd->customParam[PCP_ORIENTATION].maxVal < 1) {

                DBGMSG(DBG_LEVEL_ERROR,
                       "Device does not support orientation 1.\n");
            }

            params[hppd->customParam[PCP_ORIENTATION].dwOrder - 1] = 1;
        }
    }

    params[hppd->customParam[PCP_WIDTH].dwOrder - 1] = xlen;
    params[hppd->customParam[PCP_HEIGHT].dwOrder - 1] = ylen;

    // Use minimum width and height offsets

    params[hppd->customParam[PCP_WIDTHOFFSET].dwOrder - 1] =
        hppd->customParam[PCP_WIDTHOFFSET].minVal;

    params[hppd->customParam[PCP_HEIGHTOFFSET].dwOrder - 1] =
        hppd->customParam[PCP_HEIGHTOFFSET].minVal;

    // Emit custom page size parameters and invocation string

    for (index=0; index < MAXPCP; index++)
        psprintf(pdev, "%f ", params[index]);
    psputs(pdev, hppd->pCustomSizeCode);
    psputs(pdev, "\n");
}
Exemple #5
0
BOOL
bOutputHeader(
    PDEVDATA pdev
)

/*++

Routine Description:

    Send PostScript output header to the printer

Arguments:

    pdev - Pointer to our DEVDATA

Return Value:

    TRUE if successful, FALSE otherwise

--*/

{
    CHAR           *pstr;
    HPPD            hppd = pdev->hppd;
    ENG_TIME_FIELDS localtime;

    //
    // Process information in the public devmode fields and map it to printer
    // feature selections. This must be called before PsSelectPrinterFeatures.
    //

    HandlePublicDevmodeOptions(pdev);

    //
    // Spit out job control stuff at the beginning of a job if necessary
    //

    if (! bPageIndependence(pdev) &&
            ! (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_NO_JOB_CONTROL))
    {
        if (PpdSupportsProtocol(hppd, PROTOCOL_PJL)) {

            // Universal exit language

            if (hppd->pJclBegin != NULL) {

                psputs(pdev, hppd->pJclBegin);
            } else {

                DBGMSG(DBG_LEVEL_TERSE, "No JCLBegin code.\n");
                psputs(pdev, "\033%-12345X");
            }

            // If the printer uses PJL commands to set resolution,
            // then do it before the job.

            SetResolution(pdev, pdev->dm.dmPublic.dmPrintQuality, RESTYPE_JCL);

            // Select printer specific features - JCLSetup

            PsSelectPrinterFeatures(pdev, ODS_JCLSETUP);

            // if the printer supports job switching, put the printer into
            // postscript mode now.

            if (hppd->pJclToPs != NULL) {

                psputs(pdev, hppd->pJclToPs);
            } else {

                DBGMSG(DBG_LEVEL_TERSE, "No JCLToPSInterpreter code.\n");
                psputs(pdev, "@PJL ENTER LANGUAGE=POSTSCRIPT\n");
            }

        } else if (PpdSupportsProtocol(hppd, PROTOCOL_SIC)) {

            // directly call pswrite to output the necessary escape commands.
            // psputs will NOT output '\000'.

            pswrite(pdev, "\033\133\113\030\000\006\061\010\000\000\000\000\000", 13);
            pswrite(pdev, "\000\000\000\000\000\000\000\000\004\033\133\113\003", 13);
            pswrite(pdev, "\000\006\061\010\004", 5);

        } else if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_CTRLD_BEFORE) {

            // send a ^D before the job

            pswrite(pdev, "\004", 1);
        }
    }

    psputs(pdev, "%!PS-Adobe-3.0\n");

    // output the title of the document.

    if (pdev->pwstrDocName) {

        CHAR    buf[128];

        CopyUnicode2Str(buf, pdev->pwstrDocName, 128);

        psprintf(pdev, "%%%%Title: %s\n", buf);
    } else
        psputs(pdev, "%%Title: Untitled Document\n");

    // let the world know who we are.

    psputs(pdev, "%%Creator: Windows NT 4.0\n");

    // print the date and time of creation.

    EngQueryLocalTime(&localtime);

    psprintf(pdev, "%%%%CreationDate: %d:%d %d/%d/%d\n",
             localtime.usHour,
             localtime.usMinute,
             localtime.usMonth,
             localtime.usDay,
             localtime.usYear);

    if (! (pdev->dwFlags & PDEV_EPSPRINTING_ESCAPE))
        psputs(pdev, "%%Pages: (atend)\n");

    // mark the bounding box of the document.

    psputs(pdev, "%%BoundingBox: ");

    psprintf(pdev, "%d %d %d %d\n",
             PSREAL2INT(pdev->CurForm.ImageArea.left),
             PSREAL2INT(pdev->CurForm.ImageArea.bottom),
             PSREAL2INT(pdev->CurForm.ImageArea.right),
             PSREAL2INT(pdev->CurForm.ImageArea.top));


    if (pdev->cCopies > 1)
        psprintf(pdev, "%%%%Requirements: numcopies(%d) collate\n", pdev->cCopies);

    DscLanguageLevel(pdev, pdev->hppd->dwLangLevel);
    DscOutputFontComments(pdev, FALSE);

    // we are done with the comments portion of the document.

    psputs(pdev, "%%EndComments\n");

    // If the printer uses exitserver commands to set
    // resolution, then do it before any other PS code.

    SetResolution(pdev, pdev->dm.dmPublic.dmPrintQuality, RESTYPE_EXITSERVER);

    // define our procedure set.

    if (!(pdev->dwFlags & PDEV_EPSPRINTING_ESCAPE)) {

        psputs(pdev, "%%BeginProlog\n");
        DownloadNTProcSet(pdev, TRUE);
        psputs(pdev, "%%EndProlog\n");
    }

    // do the device setup.

    psputs(pdev, "%%BeginSetup\n");

    // set job and wait timeout values

    SetTimeoutValues(pdev);

    // Set number of copies

    psprintf(pdev, "/#copies %d def\n", pdev->cCopies);

    // Select printer specific features - DocumentSetup and AnySetup

    PsSelectPrinterFeatures(pdev, ODS_DOCSETUP|ODS_ANYSETUP);

    // The implemention of EPSPRINTING escape here just follows Win31

    if ((pdev->dwFlags & PDEV_EPSPRINTING_ESCAPE) &&
            (pdev->dm.dmPublic.dmOrientation == DMORIENT_LANDSCAPE))
    {
        SetLandscape(pdev, TRUE, pdev->CurForm.PaperSize.height, pdev->CurForm.PaperSize.width);
    }

    //
    // Invert the default transfer function if Negative Output option is selected
    //

    if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_NEG) {

        psputs(pdev, "[currenttransfer /exec load {1 exch sub} /exec load] cvx settransfer\n");
    }

    psputs(pdev, "%%EndSetup\n");

    // the form-tray information has already been sent for the first page.

    pdev->dwFlags &= ~PDEV_RESETPDEV;

    return(TRUE);
}
Exemple #6
0
VOID
PsSelectFormAndTray(
    PDEVDATA    pdev
)

/*++

Routine Description:

    This function pick the tray for a particular form selected, depends on
    the user request in the UI

Arguments:

    pdev - Pointer to our PDEVDATA

Return Value:

    NONE

--*/

{
    BOOL            IsManual;
    PINPUTSLOT      pInputSlot;
    HPPD            hppd = pdev->hppd;
    PSTR            pstr;

    // If a valid input slot is specified, then we'll instruct
    // the printer to draw paper from that slot. Otherwise,
    // we'll tell printer to select input slot based on paper size.

    IsManual = FALSE;
    pInputSlot = NULL;

    if ((pdev->dm.dmPublic.dmFields & DM_DEFAULTSOURCE)    &&
            (pdev->dm.dmPublic.dmDefaultSource != DMBIN_FORMSOURCE))
    {
        DWORD   SlotNum, cInputSlots;

        SlotNum = pdev->dm.dmPublic.dmDefaultSource;
        cInputSlots = UIGROUP_CountOptions(hppd->pInputSlots);

        if (SlotNum == DMBIN_MANUAL || SlotNum == DMBIN_ENVMANUAL) {

            // Manual feed is requested

            IsManual = TRUE;

        } else if (SlotNum >= DMBIN_USER && SlotNum < DMBIN_USER+cInputSlots) {

            // A valid input slot is requested

            pInputSlot = (PINPUTSLOT)
                         LISTOBJ_FindIndexed(
                             (PLISTOBJ) hppd->pInputSlots->pUiOptions,
                             SlotNum - DMBIN_USER);
        }

    } else if (pdev->CurForm.FormName[0] != NUL) {

        // No input slot is specifically requested. Go through
        // the form to tray assignment table and find the input
        // slot matching the requested form.

        pInputSlot = MatchFormToTray(pdev, &IsManual);
    }

    if (IsManual) {

        // If manual feed feature is requested, then
        // generate PostScript code to enable it.

        PsSelectManualFeed(pdev, TRUE);

    } else {

        // Disable manual feed if it's currently enabled

        PsSelectManualFeed(pdev, FALSE);

        if (pInputSlot != NULL) {

            // If an input slot is designated, then generate
            // PostScript code to select it.

            DscBeginFeature(pdev, "InputSlot ");
            psprintf(pdev, "%s\n", pInputSlot->pName);

            if (pInputSlot->pInvocation != NULL)
                psputs(pdev, pInputSlot->pInvocation);

            DscEndFeature(pdev);
        }
    }

    if (IsCustomPrinterForm(& pdev->CurForm)) {

        // If the custom page size is requested, then generate
        // appropriate PostScript code to send to the printer.

        DscBeginFeature(pdev, "CustomPageSize\n");
        PsSelectCustomPageSize(pdev);
        DscEndFeature(pdev);

    } else if (pInputSlot == NULL || pInputSlot->bReqPageRgn) {

        BOOL            bRegion;
        PMEDIAOPTION    pMediaOption;

        // If an input slot was selected and it doesn't require
        // PageRegion, then we are done. Otherwise, we need to
        // generate either PageRegion or PageSize code (depending
        // on whether a tray was selected).

        bRegion = IsManual || (pInputSlot != NULL);

        DscBeginFeature(pdev, bRegion ? "PageRegion" : "PageSize");
        psprintf(pdev, " %s\n", pdev->CurForm.PaperName);

        // Find the invocation string to send to the printer

        pMediaOption = (PMEDIAOPTION)
                       LISTOBJ_FindIndexed(
                           (PLISTOBJ) hppd->pPageSizes->pUiOptions,
                           pdev->CurForm.featureIndex);

        if (pMediaOption != NULL) {

            pstr = bRegion ?
                   pMediaOption->pPageRgnCode :
                   pMediaOption->pPageSizeCode;

            if (pstr != NULL) {
                psputs(pdev, pstr);
            }
        }

        DscEndFeature(pdev);
    }
}
Exemple #7
0
BOOL
bSendDeviceSetup(
    PDEVDATA pdev
)

/*++

Routine Description:

    Send page setup code to the printer. This is called at the
    beginning of every page.

Arguments:

    pdev - Pointer to our DEVDATA structure

Return Value:

    TRUE if successful, FALSE if error

--*/

{
    PSTR    pstr;
    HPPD    hppd = pdev->hppd;

    //
    // Clear the current page if Negative Output option is selected
    //

    if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_NEG) {

        psputs(pdev, "gsave clippath 1 setgray fill grestore\n");
    }

    // Rotate 90 degrees counterclockwise for normal landscape
    // or 90 degrees clockwise for rotated landscape

    if (pdev->dm.dmPublic.dmOrientation == DMORIENT_LANDSCAPE) {

        SetLandscape(pdev,
                     (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_LSROTATE) != 0,
                     pdev->CurForm.PaperSize.height,
                     pdev->CurForm.PaperSize.width);
    }

    if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_MIRROR) {

        psprintf(pdev,
                 "%f %f translate -1 1 scale\n",
                 pdev->CurForm.ImageArea.right - pdev->CurForm.ImageArea.left,
                 0);
    }

    /* Translate origin to upper left corner a la GDI */

    psprintf(pdev, "%f %f translate ",
             pdev->CurForm.ImageArea.left,
             pdev->CurForm.ImageArea.top);

    /* Flip y-axis to point downwards and scale from points to dpi */

    psprintf(pdev, "%d %d div dup neg scale\n", 72, pdev->dm.dmPublic.dmPrintQuality);

    /* Snap to pixel */

    psputs(pdev,
           "0 0 transform .25 add round .25 sub exch .25 add "
           "round .25 sub exch itransform translate\n");

    return TRUE;
}
Exemple #8
0
VOID
PsSelectPrinterFeatures(
    PDEVDATA    pdev,
    WORD        section
)

/*++

Routine Description:

    Select printer specific feature to appear in a
    given section.

Arguments:

    pdev - Pointer to our DEVDATA structure
    section - DSC section we're currently in

Return Value:

    NONE

--*/

{
    WORD         index;
    PFEATUREDATA pFeatureData;
    PUIGROUP     pUiGroup;
    PUIOPTION    pUiOption;

    //
    // Prepare data for handling printer specific feature if it's not done already.
    //

    if (!pdev->pFeatureData && !PrepareFeatureData(pdev)) {

        DBGERRMSG("PrepareFeatureData");
        return;
    }

    //
    // For each requested feature, check if it should be sent to
    // the printer in the current DSC section.
    //

    for (index = 0, pFeatureData = pdev->pFeatureData;
            index < pdev->cSelectedFeature;
            index ++, pFeatureData++)
    {
        //
        // Find the UIOPTION object corresponding to the requested feature/selection.
        //
        // HACK: PageSize feature is handled differently here because it involves
        // lots of legacy stuff which we don't want to touch at this point.
        //

        if (! (pFeatureData->section & section))
            continue;

        if (pdev->hppd->pPageSizes &&
                pdev->hppd->pPageSizes->featureIndex == pFeatureData->feature)
        {
            PsSelectFormAndTray(pdev);

        } else if (PpdFindFeatureSelection(
                       pdev->hppd,
                       pFeatureData->feature,
                       pFeatureData->option,
                       &pUiGroup,
                       &pUiOption))
        {
            DBGMSG1(DBG_LEVEL_VERBOSE, "Feature: %s\n", pUiGroup->pName);
            DBGMSG1(DBG_LEVEL_VERBOSE, "Selection: %s\n", pUiOption->pName);

            //
            // If we're not in JCLSetup section, then enclose the feature
            // invocation in a mark/cleartomark pair.
            //

            if (section != ODS_JCLSETUP) {

                DscBeginFeature(pdev, pUiGroup->pName);
                psprintf(pdev, " %s\n", pUiOption->pName);
            }

            if (pUiOption->pInvocation)
                psputs(pdev, pUiOption->pInvocation);

            if (section != ODS_JCLSETUP)
                DscEndFeature(pdev);
        }
    }
}
Exemple #9
0
BOOL bOutput24bppBitmapAsMask(
    PDEVDATA pdev,
    SURFOBJ *psoSrc,
    PPOINTL pptlSrc,
    PRECTL  prclDst)
{
    RGBTRIPLE *prgbAlt = NULL;
    PBYTE      pjStart,pjBits;
    int        x,y;
    LONG       cx,cy,xLeft,yTop;

// compute the area to actualy draw, the smaller of the src or dest

    xLeft = max(0,pptlSrc->x);
    yTop  = max(0,pptlSrc->y);
    cx    = min(prclDst->right - prclDst->left,psoSrc->sizlBitmap.cx - xLeft);
    cy    = min(prclDst->bottom - prclDst->top,psoSrc->sizlBitmap.cy - yTop);

// first go over the bitmap to find the first non white pixel

    pjStart = (PBYTE)psoSrc->pvScan0 +
             xLeft * sizeof(RGBTRIPLE) +
             yTop  * psoSrc->lDelta;

    pjBits = pjStart;

    for (y = yTop; (prgbAlt == NULL) && (y < (yTop + cy));
         ++y, pjBits += psoSrc->lDelta)
    {
        RGBTRIPLE *prgb = (RGBTRIPLE*)pjBits;

        for (x = xLeft; x < (xLeft + cx); ++x, ++prgb)
        {
            if ((prgb->rgbtBlue & prgb->rgbtGreen & prgb->rgbtRed) != 0xff)
            {
            // found a non white pixel

                prgbAlt = prgb;
                break;
            }
        }
    }

    if (prgbAlt == NULL)
        return(TRUE);

// prgbAlt now points to an RGB value for the alternate color.  If we didn't
// find an alternate color we use white.  In the future for performance we could
// replace the ROP by SRCCOPY.  Not much reason to optimize for this case now
// since it shouldn't happen

// output the header information

    psputs(pdev, "gsave\n");

    psprintf(pdev, "%d %d translate\n", prclDst->left, prclDst->top);
    psprintf(pdev, "%d %d scale\n", cx, cy);

// r g b setrgbcolor

    psprintf(pdev, "%d 256 div ", prgbAlt->rgbtRed);
    psprintf(pdev, "%d 256 div ", prgbAlt->rgbtGreen);
    psprintf(pdev, "%d 256 div setrgbcolor\n", prgbAlt->rgbtBlue);

	psprintf(pdev, "/str2 %d string def\n", (cx+7) / 8);

// size of mask

    psprintf(pdev, "%d %d", cx, cy);

// paint the 0's, leave the 1's alone

    psputs(pdev, "\nfalse\n");

// [cx 0 0 cy 0 0]

	psprintf(pdev, "[%d 0 0 %d 0 0]\n", cx, cy);

// get ready for the data

    psputs (pdev, "{currentfile str2 readhexstring pop}bind imagemask\n");

// Now go through the bitmap output ascii hex values for each byte of the mask.
// 1's should be left alone, 0's should be set to the alternate color.

    pjBits = pjStart;

    for (y = yTop; y < (yTop + cy); ++y, pjBits += psoSrc->lDelta)
    {
        RGBTRIPLE *prgb = (RGBTRIPLE*)pjBits;
        int c = 0;

        for (x = xLeft; x < (xLeft + cx);)
        {
            BYTE jMask;
            int  i;

            for (i = 0; (i < 8) && (x < (xLeft + cx)); ++i, ++x, ++prgb)
            {

                jMask <<= 1;

                if ((prgb->rgbtBlue & prgb->rgbtGreen & prgb->rgbtRed) == 0xff)
                {
                // non white pixel

                    jMask |= 1;
                }
            }

        // if we got to the end without filling up the last byte, fill it with 1's

            jMask = (jMask << (8 - i)) | ajOrBits[i];

            psputhex(pdev, 1, &jMask);

        // add a line feed every 80 bytes of data

            if ((c++ == 80) &&
                (x < (xLeft + cx)))
            {
                c = 0;
                psputs(pdev,"\n");
            }
        }
        psputs(pdev,"\n");
    }

// restore the state

    psputs(pdev,"grestore\n");

    return(TRUE);
}
Exemple #10
0
VOID
ps_setrgbcolor(
    PDEVDATA  pdev,
    PSRGB    *prgb
    )

/*++

Routine Description:

    Select a new color into the current graphics state

Arguments:

    pdev - Points to our DEVDATA structure
    prgb - Specifies the new color to be selected

Return Value:

    NONE

--*/

{
    if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_BLACK) {

        // If monochrome flag is set, map all non-white colors to black

        if (*((ULONG *) prgb) == RGB_WHITE)
            psputs(pdev, "1 g\n");
        else
            psputs(pdev, "0 g\n");

    } else if (pdev->cgs.ulColor != *((ULONG *) prgb)) {

        PS_FIX psfxRed, psfxGreen, psfxBlue;

        // Save the new color in the current graphics state structure.

        pdev->cgs.ulColor = *((ULONG *) prgb);

        // Convert RGB values from integers in the range of 0-255
        // to 24.8 fixed-point values:
        //  fixValue = (rgbValue << 8) / 255
        //
        // Here, we use a simpler formula here to achieve similar results.

        psfxRed = prgb->red;
        if (psfxRed > 128) psfxRed++;

        psfxGreen = prgb->green;
        if (psfxGreen > 128) psfxGreen++;

        psfxBlue = prgb->blue;
        if (psfxBlue > 128) psfxBlue++;

        if (pdev->dm.dmPublic.dmColor == DMCOLOR_COLOR) {

            // If all color components have equal value, just output a
            // gray scale value. Otherwise, output the RGB value.
    
            if (psfxRed == psfxGreen && psfxRed == psfxBlue) {
                psprintf(pdev, "%f g\n", psfxRed);
            } else {
                psprintf(pdev, "%f %f %f r\n", psfxRed, psfxGreen, psfxBlue);
            }

        } else {

            // Convert RGB color to grayscale using NTSC formula
            // and output the grayscale value to the printer.

            psprintf(pdev, "%f g\n", RgbToGray(psfxRed, psfxGreen, psfxBlue));
        }
    }
}