#include <grndprnt.h>
Inheritance diagram for GRenderPrint:
Public Member Functions | |
GRenderPrint (DocRect ClipRegion, Matrix ConvertMatrix, FIXED16 ViewScale, UINT32 Depth, double dpi) | |
GRenderPrint constructor. Doesn't do anything actually, just calls base class. INT32 dpi changed to double dpi (12/12/95) to improve the range of values allowed at the < 1000dpi settings that we will be using. | |
~GRenderPrint () | |
GRenderPrint destructor. Frees up the bitmap. | |
virtual BOOL | StartRender () |
Calls GRenderDIB::StartRender Initialises the bitmap to white (0xff) Disables colour separation (this is done as a post-process on the final bitmap in DisplayBits()). | |
virtual BOOL | StopRender () |
Stops rendering in this RR Restores the ColourPlate separation options and calls GRenderDIB::StopRender. | |
virtual BOOL | InitDevice () |
Initialise the device specific mechanisms for this render region. For a print region, it makes sure the StretchBlt mode is set up correctly so we get half-toning. | |
virtual BOOL | SetFirstBand () |
Sets up for banded rendering. This class does not do banded rendering as yet. This just sets things up to indicate that everything will be done in one band. | |
virtual BOOL | GetNextBand () |
Since this class does not do banded rendering, there are never any more bands. | |
Protected Member Functions | |
LPBITMAPINFO | GetLPBits (INT32 Width, INT32 Height, INT32 Depth, LPBYTE *) |
Allocates a bitmap from the CCMalloc heap. | |
void | FreeLPBits (LPBITMAPINFO, LPBYTE) |
Frees the memory allocated in GetLPBits. | |
BOOL | DisplayBits (LPBITMAPINFO lpDisplayBitmapInfo=NULL, LPBYTE lpDisplayBits=NULL) |
Output the bitmap in a printer-friendly way. | |
Protected Attributes | |
BOOL | OldPlateDisabledState |
BOOL | HaveDisabledPlate |
Definition at line 117 of file grndprnt.h.
|
GRenderPrint constructor. Doesn't do anything actually, just calls base class. INT32 dpi changed to double dpi (12/12/95) to improve the range of values allowed at the < 1000dpi settings that we will be using.
Definition at line 142 of file grndprnt.cpp. 00144 : GRenderDIB( ClipRegion, ConvertMatrix, ViewScale, Depth, dpi) 00145 { 00146 // If nobody has found us a sensible colour context yet, we'll just go for a global 00147 // default context 00148 if (CurrentColContext == NULL) 00149 CurrentColContext = ColourContext::GetGlobalDefault(COLOURMODEL_RGBT); 00150 00151 // We are printing 00152 RenderFlags.Printing = TRUE; 00153 00154 // We have not poked about in the RenderView's ColourPlates (yet) 00155 OldPlateDisabledState = FALSE; 00156 HaveDisabledPlate = FALSE; 00157 00158 TRACEUSER( "Tim", _T("ClipRegion = (%ld, %ld), (%ld, %ld)\n"), 00159 ClipRegion.lo.x, ClipRegion.lo.y, 00160 ClipRegion.hi.x, ClipRegion.hi.y); 00161 }
|
|
GRenderPrint destructor. Frees up the bitmap.
Definition at line 281 of file grndprnt.cpp. 00282 { 00283 // we should NOT delete the CurrentColContext cos we didn't alloc it - we just 00284 // got a pointer to something allocated by somebody else 00285 00286 // Free up the bitmap here, as the call to FreeLPBits in the 00287 // GRenderDIB will not call the correct version (the virtual-ness will be 00288 // broken as it is called from a destructor 00289 if (pBitmapInfo!=NULL) 00290 { 00291 // FreeLPBits( pBitmapInfo, pBits ); 00292 FreeOffscreenState(); 00293 pBitmapInfo = NULL; 00294 pBits = NULL; 00295 } 00296 }
|
|
Output the bitmap in a printer-friendly way.
Reimplemented from GRenderDIB. Definition at line 352 of file grndprnt.cpp. 00353 { 00354 00355 CCDC * pCCDC = CCDC::ConvertFromNativeDC(RenderDC); 00356 BOOL ToNativePS = (pCCDC->IsKindOf(CC_RUNTIME_CLASS(PSPrintDC))); 00357 00358 if (ToNativePS) 00359 { 00360 // wxPostscriptDC does not really support stretched blitting of bitmaps. On a good day 00361 // when it works it scales the bitmap before outputting it, which means the PS is huge 00362 // So we get our native DC to do it. 00363 00364 // Note that this colour corrects, and separates for us. 00365 00366 // Set up a PrintPSRenderRegion with the same parameters 00367 PrintPSRenderRegion * pRender = new PrintPSRenderRegion(CurrentClipRect, RenderMatrix, ScaleFactor); 00368 ERROR2IF(!pRender, FALSE, "Cannot create PrintPSRenderRegion"); 00369 00370 // Try and create the bitmap etc 00371 if (!pRender->AttachDevice(RenderView, RenderDC, NULL) || !pRender->StartRender()) 00372 { 00373 delete pRender; 00374 ERROR2(FALSE, "Cannot attach device or start rendering"); 00375 } 00376 00377 00378 DocCoord Coords[4]; 00379 Coords[0]=DocCoord(CurrentClipRect.lo.x, CurrentClipRect.hi.y); 00380 Coords[1]=CurrentClipRect.hi; 00381 Coords[2]=DocCoord(CurrentClipRect.hi.x, CurrentClipRect.lo.y); 00382 Coords[3]=CurrentClipRect.lo; 00383 00384 // Handle rotation of the bitmap. The problem here is that the bitmap itself is always horizontally 00385 // oriented, so we need to make sure the rect we put it in is of the right orientation. 00386 ANGLE angle=0; 00387 RenderMatrix.Decompose(NULL, NULL, &angle); 00388 double dangle=angle.MakeDouble(); 00389 00390 if (dangle<0) 00391 dangle+=PI; // make angle positive 00392 00393 while (dangle>PI/4) // we really mean >0, but allow for rounding. We know it's a multiple of 90. 00394 { 00395 // rotate the coordinate set used. Note we are not rotating the coordinates 00396 DocCoord save=Coords[3]; 00397 Coords[3]=Coords[2]; 00398 Coords[2]=Coords[1]; 00399 Coords[1]=Coords[0]; 00400 Coords[0]=save; 00401 dangle-=PI/2; 00402 } 00403 00404 CWxBitmap oilbitmap(pBitmapInfo, pBits); // note this bitmap thinks it owns the bits and bitmap info 00405 pRender->DrawParallelogramBitmap(Coords, &oilbitmap); 00406 // now remove the bits and info so that the renderregion can delete them itself 00407 LPBYTE DummypBits=NULL; 00408 LPBITMAPINFO DummypBitmapInfo=NULL; 00409 oilbitmap.ExtractBitsAndInfo(&DummypBits, &DummypBitmapInfo); 00410 00411 pRender->StopRender(); 00412 00413 delete pRender; 00414 00415 return TRUE; 00416 } 00417 00418 INT32 BitmapWidth = pBitmapInfo->bmiHeader.biWidth; 00419 INT32 BitmapHeight = pBitmapInfo->bmiHeader.biHeight; 00420 00421 if (RenderView != NULL && RenderView->GetColourPlate() != NULL && 00422 !RenderView->GetColourPlate()->IsDisabled()) 00423 { 00424 // We currently can't handle anything less than 8bpp bitmaps here, as we 00425 // write the output data to our bitmap in 8bpp format. 00426 ERROR2IF(uBitmapDepth < 8, FALSE, "Unexpectedly low BPP in GRenderPrint::DisplayBits"); 00427 00428 // We're colour separating. We must separate the entire bitmap down to 00429 // an 8bpp greyscale format 00430 CWxBitmap Bitmap(pBitmapInfo, pBits); 00431 00432 // We are doing a colour separation - find the separation tables 00433 BYTE *SepTables = NULL; 00434 ColourContextCMYK *cc = (ColourContextCMYK *)RenderView->GetColourContext(COLOURMODEL_CMYK); 00435 if (cc != NULL) 00436 { 00437 SepTables = (BYTE *) CCMalloc(5 * 256 * sizeof(BYTE)); 00438 if (SepTables != NULL) 00439 { 00440 if (!cc->GetProfileTables(SepTables)) 00441 { 00442 CCFree(SepTables); 00443 SepTables = NULL; 00444 } 00445 } 00446 } 00447 ERROR2IF(SepTables == NULL, FALSE, "Can't generate separation tables in GRenderPrint::DisplayBits"); 00448 00449 ColourContext *OutputContext = RenderView->GetColourContext(COLOURMODEL_RGBT); 00450 ERROR2IF(OutputContext == NULL, FALSE, "No RGB rendering ColourContext in GRenderPrint::DisplayBits"); 00451 00452 // Get a temporary 32bpp scanline 00453 const INT32 PixelWidth = Bitmap.GetWidth(); 00454 const INT32 PixelHeight = Bitmap.GetHeight(); 00455 00456 const INT32 ByteWidth = DIBUtil::ScanlineSize(PixelWidth, 8); // Width of 8bit scanline including padding 00457 00458 Pixel32bpp *TempScanline = (Pixel32bpp *) CCMalloc(PixelWidth * sizeof(Pixel32bpp)); 00459 if (TempScanline == NULL) 00460 { 00461 ERROR3("No memory for temp scanline"); 00462 return(FALSE); 00463 } 00464 00465 BYTE *pOutputBuffer = pBits; // We'll overwrite our bitmap with the separated data 00466 for (INT32 y = 0; y < PixelHeight; y++) 00467 { 00468 // Get this scanline as a 32bpp generic structure 00469 Bitmap.GetScanline32bpp(y, TRUE, TempScanline); 00470 00471 Bitmap.ColourSeparateScanline32to8(OutputContext, SepTables, pOutputBuffer, TempScanline, PixelWidth); 00472 pOutputBuffer += ByteWidth; 00473 } 00474 00475 // Make sure that the new 8bpp bitmap has a greyscale palette on it - if it was not 8bpp, 00476 // then we must realloc the header info to get enough room in it for a 256 colour palette. 00477 if (pBitmapInfo->bmiHeader.biBitCount != 8) 00478 { 00479 FreeDIB(pBitmapInfo, NULL, NULL, FALSE); // Free the info (ONLY) 00480 pBitmapInfo = AllocDIB(PixelWidth, PixelHeight, 8, NULL, NULL, FALSE); // Realloc the info 00481 } 00482 00483 // And fill in the palette to a greyscale 00484 for (INT32 i = 0; i < 256; i++) 00485 { 00486 pBitmapInfo->bmiColors[i].rgbRed = 00487 pBitmapInfo->bmiColors[i].rgbGreen = 00488 pBitmapInfo->bmiColors[i].rgbBlue = i; 00489 00490 pBitmapInfo->bmiColors[i].rgbReserved = 0; 00491 } 00492 00493 // Free our separation tables and temporary scanline 00494 CCFree(SepTables); 00495 CCFree(TempScanline); 00496 00497 // Finally, poke the CWxBitmap we created so that it doesn't delete OUR 00498 // bitmap info and bytes (which we only lent it) when it is deleted 00499 Bitmap.BMInfo = NULL; 00500 Bitmap.BMBytes = NULL; 00501 } 00502 else 00503 { 00504 // Not colour separating, but if it's a 32bpp bitmap, we need to convert to something 00505 // that StretchDIBits (below) can understand 00506 PORTNOTE("printing", "Do not convert down BPP except under PS") 00507 if (ToNativePS && (uBitmapDepth == 32)) 00508 { 00509 // Can't plot 32bpp bitmaps to GDI as 16-bit GDI doesn't understand them, 00510 // so we convert to 24bpp bitmap in-situ and render that... 00511 00512 // How many bytes to a source scanline? 00513 const INT32 ScanlineBytes = DIBUtil::ScanlineSize(BitmapWidth, uBitmapDepth ); 00514 00515 // How many bytes to a destination scanline 00516 const INT32 DestlineBytes = DIBUtil::ScanlineSize(BitmapWidth, 24); 00517 00518 // Now convert the bitmap in-situ 00519 LPBYTE OriginalBuffer = pBits; 00520 LPBYTE ConvertedBuffer = pBits; 00521 00522 for (INT32 i = 0; i < BitmapHeight; i++) 00523 { 00524 DIBUtil::Convert32to24(BitmapWidth, OriginalBuffer, ConvertedBuffer); 00525 OriginalBuffer += (UINT_PTR) ScanlineBytes; 00526 ConvertedBuffer += (UINT_PTR) DestlineBytes; 00527 } 00528 00529 // Update bitmap info to show it is now a 24bpp bitmap... 00530 pBitmapInfo->bmiHeader.biBitCount = 24; 00531 pBitmapInfo->bmiHeader.biSizeImage = DestlineBytes * BitmapHeight; 00532 } 00533 } 00534 00535 WinRect clip; 00536 //RenderDC->GetClipBox(&clip); 00537 clip = OSRenderRegion::DocRectToWin(RenderView, RenderMatrix, CurrentClipRect, 0, 0, 0, 0); 00538 00539 PORTNOTE("printing", "Attempt to use StaticPlotBitmap instead of StretchDIBits") 00540 #ifndef EXCLUDE_FROM_XARALX 00541 INT32 Scanlines = StretchDIBits(RenderDC->m_hDC, 00542 clip.left, clip.top, 00543 clip.Width(), clip.Height(), 00544 0, 0, 00545 BitmapWidth, BitmapHeight, 00546 pBits, 00547 pBitmapInfo, 00548 DIB_RGB_COLORS, 00549 SRCCOPY); 00550 00551 ERROR3IF(Scanlines == GDI_ERROR, "No scanlines copied in GRenderPrint::DisplayBits()!"); 00552 #else 00553 00554 00555 // First of all get it into a bitmap we can understand 00556 wxBitmap Bitmap(BitmapWidth, BitmapHeight, 24); 00557 wxMemoryDC MemDC; 00558 MemDC.SelectObject(Bitmap); 00559 GRenderRegion::StaticPlotBitmap(&MemDC, DIB_RGB_COLORS, pBitmapInfo, pBits, 0, 0, BitmapWidth, BitmapHeight, NULL, 0, 0); 00560 00561 //Bitmap.SaveFile(_T("/tmp/x.png"), wxBITMAP_TYPE_PNG); 00562 00563 // Now blit this to the printer, stretching as appropriate 00564 #if 0 00565 RenderDC->Blit(clip.x, clip.y, clip.GetWidth(), clip.GetHeight(), &MemDC, 0, 0); 00566 #else 00567 INT32 fwidth = clip.GetWidth(); 00568 INT32 fheight = clip.GetHeight(); 00569 wxBitmap bitmap( (int)/* TYPENOTE: Correct */fwidth, (int)/* TYPENOTE: Correct */fheight, 24 ); 00570 wxMemoryDC memDC; 00571 memDC.SelectObject(bitmap); 00572 memDC.Blit(0, 0, fwidth, fheight, &MemDC, 0, 0); 00573 00574 //bitmap.SaveFile(_T("/tmp/y.png"), wxBITMAP_TYPE_PNG); 00575 00576 RenderDC->DrawBitmap(bitmap, clip.x, clip.y); 00577 #endif 00578 #endif 00579 00580 return TRUE; 00581 }
|
|
Frees the memory allocated in GetLPBits.
Reimplemented from GRenderDIB. Definition at line 663 of file grndprnt.cpp. 00664 { 00665 // Free up the memory. Not from Limited Heap 00666 FreeDIB(lpBMI, lpB, NULL, FALSE); 00667 }
|
|
Allocates a bitmap from the CCMalloc heap.
Reimplemented from GRenderDIB. Definition at line 640 of file grndprnt.cpp. 00641 { 00642 // Get a DIB out of the CCMalloc heap 00643 LPBITMAPINFO bmInfo = NULL; 00644 bmInfo = AllocDIB( Width, Height, Depth, lplpBits, NULL, FALSE); 00645 00646 // return it. 00647 return bmInfo; 00648 }
|
|
Since this class does not do banded rendering, there are never any more bands.
Reimplemented from GRenderDIB. Definition at line 619 of file grndprnt.cpp. 00620 { 00621 // No banding 00622 return FALSE; 00623 }
|
|
Initialise the device specific mechanisms for this render region. For a print region, it makes sure the StretchBlt mode is set up correctly so we get half-toning.
Reimplemented from GRenderRegion. Definition at line 317 of file grndprnt.cpp. 00318 { 00319 // Call the base class *first* 00320 BOOL Worked = GRenderDIB::InitDevice(); 00321 00322 if (!Worked) 00323 return FALSE; 00324 00325 // if we don't do this, bitmaps printed at the same DPI as the printer come 00326 // out completely crap on NT drivers 00327 // Note: although this is claimed to be a Win32s-compatible function, 00328 // GDI16 generates an error for it (invalid value 4) 00329 // Note2: The MFC version of this function looks like the 16-bit API call, 00330 // so we call the API directly here. 00331 PORTNOTE("printing", "Don't SetStretchBltMode") 00332 #ifndef EXCLUDE_FROM_XARALX 00333 ::SetStretchBltMode(RenderDC->m_hDC, HALFTONE); 00334 #endif 00335 00336 return TRUE; 00337 }
|
|
Sets up for banded rendering. This class does not do banded rendering as yet. This just sets things up to indicate that everything will be done in one band.
Reimplemented from GRenderDIB. Definition at line 597 of file grndprnt.cpp. 00598 { 00599 // No Banding needed 00600 IsRegionBanded = FALSE; 00601 IsWaitingForRAM = FALSE; 00602 IsLastBand = TRUE; 00603 return TRUE; 00604 }
|
|
Calls GRenderDIB::StartRender Initialises the bitmap to white (0xff) Disables colour separation (this is done as a post-process on the final bitmap in DisplayBits()).
Reimplemented from GRenderRegion. Definition at line 182 of file grndprnt.cpp. 00183 { 00184 // call base class first 00185 const BOOL ok = GRenderDIB::StartRender(); 00186 if (!ok) 00187 return FALSE; 00188 00189 // we need a white background, which on non-palette devices (all we can cope 00190 // with currently) is 0xFF a lot. 00191 memset( pBits, 0xFF, pBitmapInfo->bmiHeader.biSizeImage ); 00192 00193 // If we're colour separating then we want to DISABLE separations for the entire 00194 // rendering-to-a-bitmap process, and we will then colour separate the resultant 00195 // bitmap as it is output. We remember the previous ColourPlate disabled state 00196 // so that we can restore it in StopRender (well, in DisplayBits() in fact) 00197 ERROR3IF(RenderView != NULL && RenderView->GetColourPlate() != NULL && 00198 HaveDisabledPlate && !RenderView->GetColourPlate()->IsDisabled(), 00199 "ColourPlate seems to have myseteriously become re-enabled in GRenderPrint"); 00200 if (!HaveDisabledPlate && RenderView != NULL && RenderView->GetColourPlate() != NULL) 00201 { 00202 // We must disable all colour plates for colour contexts attached to this view. 00203 // We find all the currently cached contexts for this view, and disable their ColourPlates. 00204 // These will be re-enabled in StopRender. Note that we assume that nobody outside this 00205 // rendering loop will be disabling/enabling colour plates for specific contexts - they 00206 // should be setting the state more globally by changing the View's ColourPlate. 00207 // (We should be as well, with a proper access function in view to make this possible 00208 // but I'm being a bit lazy here. If you're reading this and swearing right now, then 00209 // I apologise for any incovenience caused) 00210 for (INT32 i = 0; i < MAX_COLOURMODELS; i++) 00211 { 00212 ColourContext *Bob = RenderView->GetColourContext((ColourModel) i, TRUE); 00213 if (Bob != NULL && Bob->GetColourPlate() != NULL) 00214 Bob->GetColourPlate()->SetDisabled(TRUE); 00215 } 00216 00217 // And poke the View's main ColourPlate (so that any new contexts created during 00218 // rendering use the new state) 00219 OldPlateDisabledState = RenderView->GetColourPlate()->IsDisabled(); 00220 RenderView->GetColourPlate()->SetDisabled(TRUE); 00221 00222 // Remember that we've poked at the ColourPlate so we can re-enable it in StopRender 00223 HaveDisabledPlate = TRUE; 00224 } 00225 00226 // done OK 00227 return TRUE; 00228 }
|
|
Stops rendering in this RR Restores the ColourPlate separation options and calls GRenderDIB::StopRender.
Reimplemented from GRenderRegion. Definition at line 245 of file grndprnt.cpp. 00246 { 00247 // When colour separating we must restore the colour plate disabled state. 00248 // We assume that all contexts attached to the view should be using the same state as the 00249 // View's ColourPlate was, so we only store the one previous state for restoring from. 00250 if (HaveDisabledPlate && RenderView != NULL && RenderView->GetColourPlate() != NULL) 00251 { 00252 for (INT32 i = 0; i < MAX_COLOURMODELS; i++) 00253 { 00254 ColourContext *Bob = RenderView->GetColourContext((ColourModel) i, TRUE); 00255 if (Bob != NULL && Bob->GetColourPlate() != NULL) 00256 Bob->GetColourPlate()->SetDisabled(OldPlateDisabledState); 00257 } 00258 00259 // And restore the main View's ColourPlate 00260 RenderView->GetColourPlate()->SetDisabled(OldPlateDisabledState); 00261 OldPlateDisabledState = FALSE; 00262 HaveDisabledPlate = FALSE; 00263 } 00264 00265 // call base class *last* 00266 return GRenderDIB::StopRender(); 00267 }
|
|
Definition at line 136 of file grndprnt.h. |
|
Definition at line 135 of file grndprnt.h. |