📄 job.cpp
字号:
/*****************************************************************************\ job.cpp : Implimentation for the Job class Copyright (c) 1996 - 2001, Hewlett-Packard Co. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of Hewlett-Packard nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\*****************************************************************************/#include "header.h"#include "halftoner.h"#include "colormatch.h"#include "scaler_open.h"#include "scaler_prop.h"APDK_BEGIN_NAMESPACEextern Halftoner* Create_Halftoner( SystemServices* pSys, PrintMode* pPM, unsigned int iInputWidth, unsigned int iNumRows[], unsigned int HiResFactor, BOOL usematrix);extern Scaler* Create_Scaler(SystemServices* pSys,int inputwidth, int numerator,int denominator,BOOL vip,unsigned int BytesPerPixel);extern ColorMatcher* Create_ColorMatcher( SystemServices* pSys, ColorMap cm,unsigned int DyeCount, unsigned int iInputWidth);extern BOOL ProprietaryImaging();extern BOOL ProprietaryScaling();APDK_END_NAMESPACEAPDK_BEGIN_NAMESPACEextern float frac(float f);#define InitialPixelSize 3 // means first data into pipeline is RGB24#define Bytes(x) ((x/8)+(x%8))//////////////////////////////////////////////////////////////////////////// The Job object receives data for a contiguous set of pages targeted at// a single printer, with a single group of settings encapsulated in the// PrintContext.// At least one page will be ejected for a job, if any data at all// is printed (no half-page jobs). If settings are to be changed, this// must be done between jobs.///*!constructor - must pass a valid PrintContext to create the job.Check constructor_error for NO_ERROR before continuing.*/Job::Job( PrintContext* pPC) : thePrintContext(pPC), pSS(pPC->pSS), thePrinter(NULL), thePipeline(NULL), pText(NULL), pSender(NULL), pHalftoner(NULL), pColorMatcher(NULL), pResSynth(NULL), pBlackPlaneReplicator(NULL), pReplicator(NULL), theCompressor(NULL), pBlackPlaneCompressor(NULL), pHead(NULL),#if defined(APDK_VIP_COLORFILTERING) pErnie(NULL),#endif#if defined(APDK_FONTS_NEEDED) theTextManager(NULL),#endif CurrentMode(pPC->CurrentMode), fcount(0), skipcount(0), RowsInput(0), BlankRaster(NULL), BlackRaster(NULL), DataSent(FALSE)#ifdef APDK_USAGE_LOG , UText(0), UTextCount(0)#endif{#ifdef APDK_CAPTURE Capture_Job(pPC);#endif unsigned int i; constructor_error = NO_ERROR; if (!thePrintContext->PrinterSelected()) { constructor_error = NO_PRINTER_SELECTED; return; } thePrinter = thePrintContext->thePrinter; for (i=0; i<(unsigned)MAXCOLORPLANES; i++) if (CurrentMode->MixedRes) // means res(K) !+ res(C,M,Y) numrows[i] = CurrentMode->ResolutionX[i] / CurrentMode->BaseResX; else numrows[i]=1; ResBoost = CurrentMode->BaseResX / CurrentMode->BaseResY; if (ResBoost==0) ResBoost=1; // safety pHead = thePrinter->SelectHeader(thePrintContext); CNEWCHECK(pHead); // set up blank raster used by SendRasters constructor_error=setblankraster(); CERRCHECK; // flush any garbage out of the printer's buffer constructor_error=thePrinter->Flush(); CERRCHECK; // send the PCL header constructor_error=pHead->Send(); CERRCHECK; // set CAPy after sending header in case header used it CAPy=pHead->CAPy; constructor_error=Configure(); CERRCHECK;#if defined(APDK_FONTS_NEEDED) pText = new TextTranslator(thePrinter, pHead->QualityCode(), thePrintContext->CurrentMode->dyeCount); CNEWCHECK(pText); theTextManager = NULL; if (CurrentMode->bFontCapable) { unsigned int pixelsX = (unsigned int) (int) (thePrintContext->printablewidth() * CurrentMode->BaseResX); unsigned int pixelsY = (unsigned int) (int) (thePrintContext->printableheight() * CurrentMode->BaseResY); theTextManager=new TextManager( pText, pixelsX,pixelsY ); CNEWCHECK(theTextManager); constructor_error = theTextManager->constructor_error; CERRCHECK; }#endif if (!thePrintContext->ModeAgreesWithHardware(TRUE)) constructor_error = WARN_MODE_MISMATCH;#ifdef APDK_USAGE_LOG UHeader[0]='\0';#endif} //JobDRIVER_ERROR Job::SetupHalftoning(HALFTONING_ALGORITHM eHT)// Subroutine of Job constructor to handle ColorMatcher/Halftoner initialization.// OutputWidth set in InitScaler (it is not the ultimate width if horizontal doubling is needed)// Has to decide whether to use matrix or fast-error-diffusion, open or proprietary.{// first level of decision on matrix-vs.FED is the printmode setting itself BOOL usematrix = (eHT == MATRIX);// but this is overridden in speed-optimized builds// we also can simulate the build-switch at runtime in the test harness#ifdef APDK_OPTIMIZE_FOR_SPEED usematrix = TRUE;#endif pHalftoner = Create_Halftoner(thePrintContext->pSS, CurrentMode, OutputWidth, numrows,ResBoost,usematrix); NEWCHECK(pHalftoner); return pHalftoner->constructor_error;} //SetupHalftoningDRIVER_ERROR Job::SetupColorMatching(){ unsigned int cmWidth=InputWidth; if (pResSynth) // if 2X scaling happens before ColorMatching cmWidth *= 2; pColorMatcher = Create_ColorMatcher(thePrintContext->pSS, CurrentMode->cmap, CurrentMode->dyeCount, cmWidth); NEWCHECK(pColorMatcher); return pColorMatcher->constructor_error;} //SetupColorMatchingJob::~Job(){#ifdef APDK_CAPTURE Capture_dJob();#endif // Client isn't required to call NewPage at end of last page, so // we may need to eject a page now. if (DataSent) { newpage(); } // Tell printer that job is over. if(pHead) { pHead->EndJob(); }//end if// Delete the 4 components created in Job constructor.#if defined(APDK_FONTS_NEEDED)DBG1("deleting TextManager\n"); if (theTextManager) { delete theTextManager; }#endifDBG1("deleting RasterSender\n"); if (pSender) { delete pSender; } if (pHalftoner) { delete pHalftoner; } if (pColorMatcher) { delete pColorMatcher; } if (BlankRaster) { pSS->FreeMemory(BlankRaster); } if (BlackRaster) { pSS->FreeMemory(BlackRaster); } if (pBlackPlaneReplicator) { delete pBlackPlaneReplicator; } if (pReplicator) { delete pReplicator; } if (pResSynth) { delete pResSynth; } if (thePipeline) { delete thePipeline; } if (pHead) { delete pHead; }#if defined(APDK_VIP_COLORFILTERING) if (pErnie) { delete pErnie; }#endif if (theCompressor) { delete theCompressor; } if (pBlackPlaneCompressor) { delete pBlackPlaneCompressor; }#if defined(APDK_FONTS_NEEDED) if (pText) { delete pText; }#endif // defined(APDK_FONTS_NEEDED) if(thePrinter) { BYTE temp = 0; thePrinter->EndJob = TRUE; // the Job is done - thePrinter->Send(&temp,0); // call Send to dump any buffered data }//end ifDBG1("done with ~Job\n");} //~JobDRIVER_ERROR Job::SendCAPy(){ return pHead->SendCAPy(CAPy++);} //SendCAPy//////////////////////////////////////////////////////////////////////////////////////*!This is the fundamental method for the driver, by means of which 24bit graphics datais sent to the printer.*/DRIVER_ERROR Job::SendRasters(BYTE* ImageData) // RGB24 data for one raster// This is how graphical data is sent to the driver.// We do not check for rasters where data is supplied but happens// to be all blank (white); caller should have used NULL in this case.{#ifdef APDK_CAPTURE Capture_SendRasters(NULL, ImageData);#endif return sendrasters(NULL, ImageData);} //SendRasters//////////////////////////////////////////////////////////////////////////////////////*!This is the fundamental method for the driver, by means of which 1bit black data and 24bit RGB graphics dataare sent to the printer.*/DRIVER_ERROR Job::SendRasters(BYTE* BlackImageData, BYTE* ColorImageData) // 1bit K data and RGB24 data for one raster// This is how graphical data is sent to the driver.// We do not check for rasters where data is supplied but happens// to be all blank (white); caller should have used NULL in this case.{#ifdef APDK_CAPTURE Capture_SendRasters(BlackImageData, ColorImageData);#endif return sendrasters(BlackImageData, ColorImageData);} //SendRasters/*!This is the method for checking if an application can send data via a separate 1bit black channel*/DRIVER_ERROR Job::SupportSeparateBlack(BOOL* bSeparateBlack){ *bSeparateBlack = thePrinter->SupportSeparateBlack(); return NO_ERROR;}// internal entry point, used by newpageDRIVER_ERROR Job::sendrasters(BYTE* BlackImageData, BYTE* ColorImageData){ DRIVER_ERROR err = NO_ERROR; if (thePipeline == NULL) { return SYSTEM_ERROR; } // need to put out some data occasionally in case of all-text page, // so printer will go ahead and start printing the text before end of page if (BlackImageData == NULL && ColorImageData == NULL) { skipcount++;// fcount += ScaleFactor; if (skipcount >= 200) { skipcount=0; ColorImageData=BlankRaster; } else { fcount += ScaleFactor; } err = thePipeline->Flush(); ERRCHECK; } else { skipcount=0; DataSent=TRUE; // so we know we need a formfeed when job ends } RowsInput++; // needed in case res > 300 if (BlackImageData || ColorImageData) { if (fcount > 1000) { CAPy += fcount/1000; err = thePrinter->SkipRasters ((fcount / 1000)); // needed for Crossbow ERRCHECK; fcount =fcount % 1000; } if (BlackImageData && CurrentMode->dyeCount != 3 && CurrentMode->dyeCount != 6) { err = setblackraster(); ERRCHECK; for (unsigned int i = 0; i < thePrintContext->InputWidth / 8; i++) { unsigned char bitflag = 0x80; for (unsigned int j = 0; j < 8; j++) { if (BlackImageData[i] & bitflag) BlackRaster[i*8+j] = 1; bitflag = bitflag >> 1; } } if (thePrintContext->InputWidth % 8 > 0) { unsigned int i = thePrintContext->InputWidth / 8; unsigned char bitflag = 0x80; for (unsigned int j = 0; j < thePrintContext->InputWidth % 8; j++) { if (BlackImageData[i] & bitflag) BlackRaster[i*8+j] = 1; bitflag = bitflag >> 1; } } thePipeline->Exec->raster.rastersize[COLORTYPE_BLACK] = thePrintContext->InputWidth; thePipeline->Exec->raster.rasterdata[COLORTYPE_BLACK] = BlackRaster; } else { thePipeline->Exec->raster.rastersize[COLORTYPE_BLACK] = 0; thePipeline->Exec->raster.rasterdata[COLORTYPE_BLACK] = NULL; } if (ColorImageData) { thePipeline->Exec->raster.rastersize[COLORTYPE_COLOR] = thePrintContext->InputWidth*3; thePipeline->Exec->raster.rasterdata[COLORTYPE_COLOR] = ColorImageData; } else { thePipeline->Exec->raster.rastersize[COLORTYPE_COLOR] = 0; thePipeline->Exec->raster.rasterdata[COLORTYPE_COLOR] = NULL; } err = thePipeline->Execute(&(thePipeline->Exec->raster)); } return err;} //sendrastersDRIVER_ERROR Job::newpage()// (for internal use, called by external NewPage){ sendrasters(); // flush pipeline DRIVER_ERROR err = pHead->FormFeed(); ERRCHECK; // reset vertical cursor counter if (thePrinter->UseGUIMode(thePrintContext->CurrentMode) && ((int) (thePrintContext->PrintableStartY () * 100)) != 0) // Venice in GUImode doesn't accept top-margin setting, so we use CAP for topmargin // Start at the top for full-bleed printing - PhotoSmart 100 for now { CAPy = thePrintContext->GUITopMargin(); } else { CAPy = 0; } skipcount = RowsInput = 0; fcount = 0;// reset flag used to see if formfeed needed DataSent = FALSE; if (!thePrintContext->ModeAgreesWithHardware(TRUE)) { return WARN_MODE_MISMATCH; }#ifdef APDK_USAGE_LOG theTranslator->PrintDotCount(UHeader); theTranslator->NextPage(); UTextCount=UText=0;#endif return NO_ERROR;} //newpage/*!Resets counters, flushes buffers, and sends a form feed to the printer.*/DRIVER_ERROR Job::NewPage()// External entry point{#ifdef APDK_CAPTURE Capture_NewPage();#endif return newpage();} //NewPagevoid Job::SetOutputWidth()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -