// // fuband.c // // August.26,1997 H.Ishida(FPL) // fuxlres.dll (NT5.0 MiniDriver) // // July.31,1996 H.Ishida (FPL) // FUXL.DLL (NT4.0 MiniDriver) // #include "fuxl.h" #include "fumh.h" #include "fumh2.h" #include "fuband.h" #include "fuimg2.h" #include "fuimg4.h" #include "fudebug.h" // // FjBAND: // In Win-F image command(RTGIMG2 and RTGIMG4), image coordinate must // be a multiple of 32. But I can't create such a GPC file for RasDD. // Some image data, not on 32x32 grid, must be buffered in FjBAND, // width:papser width, height:32, x-coordinate:0, y-coordinate:a multiple // of 32. // // Image to be output // (0, y) // A----------------------------------+ // | partA | // B----------------------------------+ // | partB | // | | // | | // C----------------------------------+ // | partC | // D----------------------------------+ // // I split source image to 3 part. // A: top of image, is not a multiple of 32. // B: top of image, is a multiple of 32. // C: bottom of image, is a multilpe of 32. // D: bottom of image, is not a multile of 32. // // partA: A to B. this part is buffered in FjBAND, ORed on // previousely written image. // partB: B to C. this part is not bufferd, output immediately. // partC: C to D. this part is buffered in FjBAND, may be ORed // partA of next image. // #define FUXL_BANDHEIGHT 32 // // void fuxlInitBand(PFUXLPDEV pFuxlPDEV) // fuxlres private PDEV // // This function initializes FjBAND, but not allocate memory for band. // void fuxlInitBand(PFUXLPDEV pFuxlPDEV) { int i; pFuxlPDEV->cBandByteWidth = (pFuxlPDEV->cxPage + 7) / 8; i = 0x10000L / pFuxlPDEV->cBandByteWidth; pFuxlPDEV->cyBandSegment = i - (i % FUXL_BANDHEIGHT); pFuxlPDEV->pbBand = NULL; pFuxlPDEV->cbBand = FUXL_BANDHEIGHT * pFuxlPDEV->cBandByteWidth; pFuxlPDEV->yBandTop = 0; pFuxlPDEV->bBandDirty = FALSE; pFuxlPDEV->bBandError = FALSE; } // // BOOL fuxlEnableBand( // PFUXLPDEV pFuxlPDEV // fuxlres private PDEV // ); // // This function allocates memory for FjBAND. // // Return Values // TRUE: band memory is allocated. // FALSE: band memory is not allocated. // BOOL fuxlEnableBand(PFUXLPDEV pFuxlPDEV) { DWORD cbBand; pFuxlPDEV->pbBand = (LPBYTE)MemAllocZ(pFuxlPDEV->cbBand); if(pFuxlPDEV->pbBand == NULL){ pFuxlPDEV->bBandError = TRUE; return FALSE; } memset(pFuxlPDEV->pbBand, 0, pFuxlPDEV->cbBand); pFuxlPDEV->bBandDirty = FALSE; return TRUE; } // // void fuxlDisableBand( // PFUXLPDEV pFuxlPDEV // fuxlres private PDEV // ); // // This function frees memory for FjBAND. // void fuxlDisableBand(PFUXLPDEV pFuxlPDEV) { if(pFuxlPDEV->pbBand != NULL){ MemFree(pFuxlPDEV->pbBand); pFuxlPDEV->pbBand = NULL; } pFuxlPDEV->bBandError = FALSE; } // // void fuxlCopyBand( // PDEVOBJ pdevobj, // MINI5 data // LPBYTE pBuff, // address of source image data. // LONG lDelta, // width of source image data(in bytes) // int y, // y-coordinate of source image. // int cy // height of source image data(scanline) // ); // // This function copies source image data to FjBAND. // // void fuxlCopyBand(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcBandWidth, int y, int cy) { PFUXLPDEV pFuxlPDEV; LPCBYTE pbSrcTmp; LPBYTE pbDst; LPBYTE pbDstTmp; int i; int j; UINT uTmp; pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM; if(pFuxlPDEV->yBandTop <= y && y + cy <= pFuxlPDEV->yBandTop + FUXL_BANDHEIGHT){ pbDst = pFuxlPDEV->pbBand + (y - pFuxlPDEV->yBandTop) * pFuxlPDEV->cBandByteWidth; uTmp = 0; for(i = cy; i > 0; --i){ pbDstTmp = pbDst; for(j = cSrcBandWidth; j > 0; --j){ uTmp |= *pbSrc; *pbDstTmp++ |= *pbSrc++; } pbDst += pFuxlPDEV->cBandByteWidth; } if(uTmp != 0) pFuxlPDEV->bBandDirty = TRUE; } } // // BOOL fuxlOutputMH( // PDEVOBJ pdevobj // MINI5 data // LPCBYTE pbSrc, // address of source image data. // LONG lDelta, // width of source image data(in byte). // int y, // y-coordinate of source image data. // int cy // height of source image data(scanline). // ); // // This function outputs image, uses FM-MH(old type). // // Return Values // TRUE: output succeeded. // FALSE: output failed. // memory allocate error, or // MH compression is not effecive for this image data. // BOOL fuxlOutputMH(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcBandWidth, int y, int cy) { BOOL bResult; LPBYTE pDest; LONG cb; LONG cDestN; DWORD cbMHData; BYTE abTmp[10]; bResult = FALSE; cb = cSrcBandWidth * cy; cDestN = (cb + 1) / 2; pDest = (LPBYTE)MemAllocZ(cDestN); if(pDest != NULL){ cbMHData = (WORD)MhCompress(pDest, cDestN, (LPBYTE)pbSrc, cSrcBandWidth * cy, cSrcBandWidth, cy); if(cbMHData > 0){ memcpy(abTmp, "\x1d\x30\x20\x62\x00\x00", 6); abTmp[6] = HIBYTE((WORD)y); abTmp[7] = LOBYTE((WORD)y); abTmp[8] = HIBYTE(cbMHData); abTmp[9] = LOBYTE(cbMHData); WRITESPOOLBUF(pdevobj, abTmp, 10); WRITESPOOLBUF(pdevobj, pDest, cbMHData); WRITESPOOLBUF(pdevobj, "\x00\x00", 2 ); bResult = TRUE; } MemFree(pDest); } return bResult; } // // BOOL fuxlOutputMH2( // PDEVOBJ pdevobj, // MINI5 data // LPCBYTE pbSrc, // address of source image data. // LONG lDelta, // width of source image data(in byte). // int y, // y-coordinate of source image data. // int cy // height of source image data(scanline). // ); // // This function outputs image, uses FM-MH2(for XL-65K and after). // // Return Value // TRUE: output succeeded. // FALSE: output failed. // memory allocate error, or // MH compression is not effective for this iamge data. // BOOL fuxlOutputMH2(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcByteWidth, int y, int cy) { BOOL bResult; LPBYTE pDest; LONG cb; LONG cDestN; DWORD cbMHData; BYTE abTmp[10]; bResult = FALSE; cb = cSrcByteWidth * cy; cDestN = (cb + 1) / 2; pDest = (LPBYTE)MemAllocZ(cDestN); if(pDest != NULL){ cbMHData = Mh2Compress(pDest, cDestN, (LPBYTE)pbSrc, cSrcByteWidth * cy, cSrcByteWidth, cy); if(cbMHData > 0){ memcpy(abTmp, "\x1d\x30\x20\x62\x00\x00", 6); abTmp[6] = HIBYTE((WORD)y); abTmp[7] = LOBYTE((WORD)y); abTmp[8] = HIBYTE(cbMHData); abTmp[9] = LOBYTE(cbMHData); WRITESPOOLBUF(pdevobj, abTmp, 10); WRITESPOOLBUF(pdevobj, pDest, cbMHData); WRITESPOOLBUF(pdevobj, "\x00\x00", 2 ); bResult = TRUE; } MemFree(pDest); } return bResult; } // // void fuxlOutputGraphics( // PDEVOBJ pdevobj, // MINI5 // LPCBYTE pbSrc, // address of source image data. // UINT bx, // width of source iamge data(in byte). // UINT y, // y-coordinate of source iamge data. // UINT cy // height of source iamge data(scanline). // ); // // This function outputs source iamge data. // void fuxlOutputGraphics(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcByteWidth, UINT y, UINT cy) { PFUXLPDEV pFuxlPDEV; DWORD dwOutputCmd; TRACEOUT(("[fuxlOutputGraphics]y %d cy %d\r\n", y, cy)) pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM; dwOutputCmd = pFuxlPDEV->dwOutputCmd; if((dwOutputCmd & OUTPUT_MH2) != 0){ TRACEOUT(("[fuxlOutputGraphics]Try MH2\r\n")) if(fuxlOutputMH2(pdevobj, pbSrc, cSrcByteWidth, y, cy) != FALSE) return; } if((dwOutputCmd & OUTPUT_RTGIMG4) != 0){ TRACEOUT(("[fuxlOutputGraphics]Send RTGIMG4\r\n")) fuxlOutputRTGIMG4(pdevobj, pbSrc, cSrcByteWidth, y, cy); return; } if((dwOutputCmd & OUTPUT_MH) != 0){ TRACEOUT(("[fuxlOutputGraphics]Try MH\r\n")) if(fuxlOutputMH(pdevobj, pbSrc, cSrcByteWidth, y, cy) != FALSE) return; } TRACEOUT(("[fuxlOutputGraphics]Send RTGIMG2\r\n")) fuxlOutputRTGIMG2(pdevobj, pbSrc, cSrcByteWidth, y, cy); } // // BOOL fuxlSetBandPos( // PDEVOBJ pdevobj, // MINI5 data // int yPos // y-coordinate // ); // // This function sets y-coordinate of FjBAND. // // Return Value. // TRUE: secceeded // FALSE: failed(FjBAND can't move upward) // // Remarks // Internally, y-coordinate is adjust to a multiple of 32. // Then check new y-coordinate, if it is equal to previous y-coordinate, // the contents of FjBAND remain. Otherwise, flushes FjBAND. // BOOL fuxlSetBandPos(PDEVOBJ pdevobj, int yPos) { PFUXLPDEV pFuxlPDEV; pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM; if(yPos < pFuxlPDEV->yBandTop) return FALSE; yPos -= yPos % FUXL_BANDHEIGHT; if(yPos != pFuxlPDEV->yBandTop){ if(pFuxlPDEV->bBandDirty != FALSE){ fuxlOutputGraphics(pdevobj, pFuxlPDEV->pbBand, pFuxlPDEV->cBandByteWidth, pFuxlPDEV->yBandTop, FUXL_BANDHEIGHT); memset(pFuxlPDEV->pbBand, 0, pFuxlPDEV->cbBand); pFuxlPDEV->bBandDirty = FALSE; } pFuxlPDEV->yBandTop = yPos; } return TRUE; } // // void fuxlRefreshBand( // PDEVOBJ pdevobj // MINI5 data // ); // // This function flushes FjBAND, send FormFeed command, and sets // y-coordinate to top(0). // void fuxlRefreshBand(PDEVOBJ pdevobj) { PFUXLPDEV pFuxlPDEV; pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM; if(pFuxlPDEV->bBandDirty != FALSE){ fuxlOutputGraphics(pdevobj, pFuxlPDEV->pbBand, pFuxlPDEV->cBandByteWidth, pFuxlPDEV->yBandTop, FUXL_BANDHEIGHT); memset(pFuxlPDEV->pbBand, 0, pFuxlPDEV->cbBand); pFuxlPDEV->bBandDirty = FALSE; } WRITESPOOLBUF(pdevobj, "\x0c", 1); // FF command pFuxlPDEV->yBandTop = 0; } // // WORD OEMFilterGraphics( // LPDV lpdv, // address of private data, used by RasDD. // LPBYTE lpBuf, // address of source iamge data. // WORD wLen // size of source image data. // ); // // This function convert image format to Printer command sequence, // and spool it. // // Return Value // the number of bytes of processed raster data. // the number of bytes may be the same as wLen, but not necessarily. // // Remarks // // | <--------------- pFuxlPDEV->cBlockWidth-----------> | // lpBuf *--------+--------+--------+--------+--------+--------+--- // | | | | | | | ^ // +--------+--------+--------+--------+--------+--------+ | // | | | | | | | pFuxlPDEV-> // +--------+--------+--------+--------+--------+--------+ cBlockHeight // | | | | | | | | // +--------+--------+--------+--------+--------+--------+ | // | | | | | | | v // +--------+--------+--------+--------+--------+--------+--- // // white dot:0 // black dot:1 // // coordinate of '*' (left-top of image): // pFuxlPDEV->x // pFuxlPDEV->y // // // MINI5 export BOOL APIENTRY OEMFilterGraphics(PDEVOBJ pdevobj, LPBYTE pbBuf, DWORD dwLen) { PFUXLPDEV pFuxlPDEV; LPCBYTE pbSrc; int y; int yAlignTop; int yBottom; int yAlignBottom; int cSrcByteWidth; int cLine; TRACEOUT(("[OEMFilterGraphics]\r\n")) pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM; if(pFuxlPDEV->pbBand == NULL){ if(pFuxlPDEV->bBandError != FALSE) return FALSE; if(fuxlEnableBand(pFuxlPDEV) == FALSE) return FALSE; } pbSrc = pbBuf; y = pFuxlPDEV->y; yAlignTop = y - (y % FUXL_BANDHEIGHT); yBottom = y + pFuxlPDEV->cBlockHeight; yAlignBottom = yBottom - (yBottom % FUXL_BANDHEIGHT); cSrcByteWidth = pFuxlPDEV->cBlockByteWidth; if(yAlignTop < y){ // partA if(fuxlSetBandPos(pdevobj, y) == FALSE) // FUXL band pos can't move up return TRUE; cLine = FUXL_BANDHEIGHT - (y - yAlignTop); if(y + cLine >= yBottom){ fuxlCopyBand(pdevobj, pbSrc, cSrcByteWidth, y, yBottom - y); return TRUE; } fuxlCopyBand(pdevobj, pbSrc, cSrcByteWidth, y, cLine); pbSrc += cSrcByteWidth * cLine; y += cLine; } if(y < yAlignBottom){ // partB if(fuxlSetBandPos(pdevobj, yAlignBottom) == FALSE) // FUXL band pos can't move up return TRUE; for(cLine = yAlignBottom - y; cLine >= pFuxlPDEV->cyBandSegment; cLine -= pFuxlPDEV->cyBandSegment){ fuxlOutputGraphics(pdevobj, pbSrc, cSrcByteWidth, y, pFuxlPDEV->cyBandSegment); pbSrc += cSrcByteWidth * pFuxlPDEV->cyBandSegment; y += pFuxlPDEV->cyBandSegment; } if(cLine > 0){ fuxlOutputGraphics(pdevobj, pbSrc, cSrcByteWidth, y, cLine); pbSrc += cSrcByteWidth * cLine; y += cLine; } } if(y < yBottom){ // partC if(fuxlSetBandPos(pdevobj, y) == FALSE) // FUXL band pos can't move up return TRUE; fuxlCopyBand(pdevobj, pbSrc, cSrcByteWidth, y, yBottom - y); } return TRUE; } // end of fuband.c