Legacy Print драйвер нечеткий - PullRequest
0 голосов
/ 09 апреля 2020

У нас есть старый драйвер печати, который принимает документ и отправляет PCL в спулер. Затем клиент обрабатывает этот PCL и отображает все как TIFF. Наши пользователи жалуются, что TIFF нечеткий, а изображение нечеткое. Мне дается эта глупая задача разгадать тайну

Является ли сам PCL плохим. У меня недостаточно знаний о PCL и о том, есть ли у него разрешение. Как перехватить вывод драйвера, который отправляется в спулер? Или это клиент, который как-то не рендерит PCL с хорошим разрешением. Нужно ли go из-за боли учиться отлаживать этот драйвер. Я буду, но это поможет мне решить проблему с решением. Я никогда не занимался разработкой драйверов, поэтому для меня это будет поворотом. Но если мне нужно сделать, то все в порядке. С чего мне начать? Является ли PCL плохим или клиент, который преобразует PCL в растровое, плохое?

Это код C ++

    BOOL APIENTRY 
    CreatePCLRasterGraphicPage(
            SURFOBJ *pso, 
            BOOL firstPage,
            char *pageText
            )
    /*++

    Routine Description:

        Creates standard PCL end-of-document lines.

    Arguments:

        SURFOBJ - Surface Object
        BOOL - First Page ?
        char * Page Text

    Return Value:

        BOOL - True if successful

    --*/
    {
        PDEVOBJ pDevObj = (PDEVOBJ)pso->dhpdev;
        POEMPDEV pOemPDEV = (POEMPDEV)pDevObj->pdevOEM;

        DWORD dwOffset = 0;
        DWORD dwWritten = 0;
        DWORD dwPageBufferSize = 0;
        int i = 0;
        ULONG n = 0;

        BYTE bitmapRow[1050];
        BYTE compRow[2100];
        DWORD dwRowSize = 0;
        DWORD dwCompPCLBitmapSize = 0;
        //wchar_t traceBuff[256];


        pOemPDEV->dwCompBitmapBufSize = 0;

        // TRACE OUT ----------------------------------------------------
        //ZeroMemory(traceBuff, 256);
        //StringCchPrintf(traceBuff, 256, L"Top of CreatePCLRasterGraphicPage");
        //WriteTraceLine(traceBuff);
        // -----------------------------------------------------------------

        // Invert color
        for (n = 0; n < pso->cjBits; n++)
            *(((PBYTE &)pso->pvBits) + n) ^= 0xFF;

        // compress each row and store in a buffer with PCL line headings
        for (i = 0; i < pso->sizlBitmap.cy; i++) {
            // Zero Memory hack for bottom of form black line
            if (*(((PBYTE &)pso->pvScan0) + (i * pso->lDelta) + 319) == 0xFF)
                ZeroMemory(((PBYTE &)pso->pvScan0) + (i * pso->lDelta), 320);

            // Copy the bitmap scan line into bitmapRow and send them off to be compressed
            ZeroMemory(bitmapRow, 1050);
            ZeroMemory(compRow, 2100);
            MoveMemory(bitmapRow, ((PBYTE &)pso->pvScan0) + (i * pso->lDelta), pso->lDelta);
            dwRowSize = CompressBitmapRow(compRow, bitmapRow, pso->lDelta);

            // Create PCL Row Heading
            char bufPCLLineHead[9];
            StringCchPrintfA(bufPCLLineHead, 9, "%c%s%d%s", 27, "*b", dwRowSize, "W");

            if ((dwCompPCLBitmapSize + dwRowSize + strlen(bufPCLLineHead)) 
                                                        > pOemPDEV->dwCompBitmapBufSize) {
                if (!GrowCompBitmapBuf(pOemPDEV)) {
                    //ZeroMemory(traceBuff, 256);
                    //StringCchPrintf(traceBuff, 256, 
                    //      L"Compressed bitmap buffer could not allocate more memory.");
                    //WriteTraceLine(traceBuff);
                }
            }

            if (pOemPDEV->pCompBitmapBufStart) {
                // write the PCL line heading to the buffer
                MoveMemory(pOemPDEV->pCompBitmapBufStart + dwCompPCLBitmapSize, 
                                        bufPCLLineHead, strlen(bufPCLLineHead));
                dwCompPCLBitmapSize += strlen(bufPCLLineHead);

                // write the compressed row to the buffer
                MoveMemory(pOemPDEV->pCompBitmapBufStart + dwCompPCLBitmapSize, 
                                        compRow, dwRowSize);
                dwCompPCLBitmapSize += dwRowSize;       
            }
        }

        // Calculate size and create buffer 
        dwPageBufferSize = 21;

        if (!firstPage)
            dwPageBufferSize++;

        bGrowBuffer(pOemPDEV, dwPageBufferSize);

        // Add all Raster Header Lines
        if (!firstPage) 
        {
            // Add a Form Feed
            char bufFormFeed[2];
            StringCchPrintfA(bufFormFeed, 2, "%c", 12);             // 1 char
            MoveMemory(pOemPDEV->pBufStart + dwOffset, bufFormFeed, 2);
            dwOffset += 1;
        }

        // Position cursor at X0, Y0
        char bufXY[8];
        StringCchPrintfA(bufXY, 8, "%c%s", 27, "*p0x0Y");           // 7 chars
        MoveMemory(pOemPDEV->pBufStart + dwOffset, bufXY, 8);
        dwOffset += 7;

        // Start Raster Graphics
        char bufStartRas[6];
        StringCchPrintfA(bufStartRas, 6, "%c%s", 27, "*r1A");       // 5 chars
        MoveMemory(pOemPDEV->pBufStart + dwOffset, bufStartRas, 6);
        dwOffset += 5;

        // Raster Encoding - Run-Length Encoding
        char bufRasEncoding[6];
        StringCchPrintfA(bufRasEncoding, 6, "%c%s", 27, "*b1M");    // 5 chars
        MoveMemory(pOemPDEV->pBufStart + dwOffset, bufRasEncoding, 6);
        dwOffset += 5;

        // Write out bitmap header PCL
        dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pOemPDEV->pBufStart, dwPageBufferSize);

        // Write out PCL plus compressed bitmap bytes
        dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pOemPDEV->pCompBitmapBufStart, dwCompPCLBitmapSize);

        // End Raster Graphics
        char bufEndRas[5];
        StringCchPrintfA(bufEndRas, 5, "%c%s", 27, "*rB");          // 4 chars
        MoveMemory(pOemPDEV->pBufStart + dwOffset, bufEndRas, 5);

        // Write out PCL end bitmap
        dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, bufEndRas, 4);

        // Free Compressed Bitmap Memory
        if (pOemPDEV->pCompBitmapBufStart) {
            MemFree(pOemPDEV->pCompBitmapBufStart);
            pOemPDEV->pCompBitmapBufStart = NULL;
            pOemPDEV->dwCompBitmapBufSize = 0;
            dwPageBufferSize = 0;
        }

        // Free Memory
        vFreeBuffer(pOemPDEV);

        // Write Page Text to the spooler
        size_t charCount = 0;
        StringCchLengthA(pageText, 32767, &charCount);

        char bufWriteText[15];
        ZeroMemory(bufWriteText, 15);
        StringCchPrintfA(bufWriteText, 15, "%c%s%d%s", 27, "(r", charCount, "W");
        dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, bufWriteText, strlen(bufWriteText));

        dwWritten = pDevObj->pDrvProcs->DrvWriteSpoolBuf(pDevObj, pageText, charCount);

        return TRUE;
    }


BOOL
GrowCompBitmapBuf(
                  POEMPDEV pOemPDEV
                  )
/*++

Routine Description:

    Grows memory by 1000 bytes (per call) to hold compressed
    bitmap and PCL data.

Arguments:

    POEMPDEV - Pointer to the private PDEV structure

Return Value:

    BOOL - True is successful

--*/
{
    DWORD dwOldBufferSize = 0;
    PBYTE pNewBuffer = NULL;

    dwOldBufferSize = pOemPDEV->pCompBitmapBufStart ? pOemPDEV->dwCompBitmapBufSize : 0;
    pOemPDEV->dwCompBitmapBufSize = dwOldBufferSize + 4096;

    pNewBuffer = (PBYTE)MemAlloc(pOemPDEV->dwCompBitmapBufSize);
    if (pNewBuffer == NULL) {
        MemFree(pOemPDEV->pCompBitmapBufStart);
        pOemPDEV->pCompBitmapBufStart = NULL;
        pOemPDEV->dwCompBitmapBufSize = 0;
        return FALSE;
    }

    if (pOemPDEV->pCompBitmapBufStart) {
        CopyMemory(pNewBuffer, pOemPDEV->pCompBitmapBufStart, dwOldBufferSize);
        MemFree(pOemPDEV->pCompBitmapBufStart);
        pOemPDEV->pCompBitmapBufStart = pNewBuffer;
    }
    else {
        pOemPDEV->pCompBitmapBufStart = pNewBuffer;
    }

    return TRUE;
}

RLE (у меня еще не было возможности добавить это). Я смотрел на разных форумах, как должен понравиться код, и это то, что я придумал. Я добавлю, протестирую документ и обновлю сообщение

 public virtual sbyte[] decompressRL(sbyte[] data, int startOffset, int width, int count)
      {
        /*type 1 compression*/
        int dataCount = count;
        List<sbyte> decompressed = new List<sbyte>();
        int numberOfDecompressedBytes = 0;
        int dataStartOffset = startOffset;

        while (dataCount-- > 0)
        {
          int cntrlByte = (int) data[dataStartOffset++];

          // Repeated pattern
          int val = data[dataStartOffset++];
          dataCount--;
          while (cntrlByte >= 0)
          {
            decompressed.Insert(numberOfDecompressedBytes++, new sbyte?((sbyte) val));
            cntrlByte--;
          }
        }

        mMaxUncompressedByteCount = numberOfDecompressedBytes;
        return getBytes(decompressed);
      }

Вот как нечетко пользователи утверждают, что изображение выглядит. Это когда печатается из документа Word в драйвер. Оригинал очень понятен. enter image description here

...