00001 // $Id: printctl.cpp 1454 2006-07-17 11:52:51Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // 00099 // Implementation of the print control class 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 #include "colcontx.h" 00107 #include "colourix.h" 00108 #include "colormgr.h" 00109 #include "colplate.h" 00110 #include "camelot.h" 00111 //#include "convert.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 //#include "justin2.h" 00115 //#include "markn.h" 00116 #include "osrndrgn.h" 00117 #include "prdlgctl.h" 00118 #include "princomp.h" 00119 #include "printctl.h" 00120 #include "prntview.h" 00121 //#include "resource.h" 00122 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00123 //#include "simon.h" 00124 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00125 //#include "tim.h" 00126 //#include "view.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00127 #include "prnmks.h" 00128 //#include "isetres.h" 00129 00130 CC_IMPLEMENT_MEMDUMP(PrintControl, CC_CLASS_MEMDUMP) 00131 CC_IMPLEMENT_MEMDUMP(PrintPatchInfo,CC_CLASS_MEMDUMP) 00132 CC_IMPLEMENT_MEMDUMP(TypesetInfo, CC_CLASS_MEMDUMP) 00133 00134 // This is not compulsory, but you may as well put it in so that the correct version 00135 // of your file can be registered in the .exe 00136 DECLARE_SOURCE("$Revision: 1454 $"); 00137 00138 #define Swap(a,b) { (a)^=(b), (b)^=(a), (a)^=(b); } 00139 00140 // This is the max DPI at which bitmaps will be printed when using automatic DPI calculations 00141 #define MAXAUTOBITMAPDPI 200 00142 00143 // These two values determine the range of values that the bitmap DPI will lie within 00144 #define MINBITMAPDPI 10 00145 #define MAXBITMAPDPI 600 00146 00147 // Constants used for initialisation 00148 #define A4_WIDTH (INT32(MM_MP_VAL*210)) // 210 mm - A4 width 00149 #define A4_HEIGHT (INT32(MM_MP_VAL*297)) // 297 mm - A4 height 00150 00151 //---------------------------------------------------------------- 00152 00153 static INT32 MinPrintScale = 5; 00154 static INT32 MaxPrintScale = 999; 00155 00156 PrintMethodType PrintControl::AppPrintMethod = PRINTMETHOD_NORMAL; // ini file entry declared in princomp.cpp 00157 00158 // if ( Camelot.DeclareSection(TEXT("Preferences"), 3) ) 00159 // { 00160 // section declared ok so now define the preference option 00161 // Camelot.DeclarePref(TEXT("Preferences"), TEXT("MinPrintScale"), &MinPrintScale, 1); 00162 // Camelot.DeclarePref(TEXT("Preferences"), TEXT("MaxPrintScale"), &MaxPrintScale, 1); 00163 00164 /****************************************************************************************** 00165 00166 > PrintControl::PrintControl() 00167 00168 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00169 Created: 27/3/95 00170 Inputs: - 00171 Outputs: - 00172 Returns: - 00173 Purpose: Default constructor 00174 Errors: - 00175 SeeAlso: - 00176 00177 ******************************************************************************************/ 00178 00179 PrintControl::PrintControl() 00180 { 00181 PrintAreaSetUp = FALSE; // We haven't set the control up with a print area yet 00182 SetUpFailed = FALSE; // We haven't called SetUp yet, so we haven't failed yet 00183 pSpread = NULL; 00184 00185 TotalPrintArea = DocRect(0,0,A4_WIDTH,A4_HEIGHT); 00186 PrintableArea = TotalPrintArea; 00187 PALeftMargin = 0; 00188 PATopMargin = 0; 00189 00190 Origin = DocCoord(0,A4_HEIGHT); 00191 00192 PageWidth = A4_WIDTH; 00193 PageHeight = A4_HEIGHT; 00194 PaperWidth = A4_WIDTH; 00195 PaperHeight = A4_HEIGHT; 00196 00197 DPS = FALSE; 00198 Bleed = 0; 00199 CropArea = CROPAREA_SIZE+OUTSIDEBLEEDWIDTH; 00200 CropTopMargin = 0; 00201 CropLeftMargin = 0; 00202 00203 // Print layout vars 00204 WholeSpread = FALSE; 00205 00206 Scale = FIXED16(100); 00207 Orient = PRINTORIENTATION_UPRIGHT; 00208 00209 FitType = PRINTFIT_BESTPAPER; 00210 00211 TopMargin = 0; 00212 LeftMargin = 0; 00213 ScaledWidth = A4_WIDTH; 00214 ScaledHeight= A4_HEIGHT; 00215 00216 Rows = 1; 00217 Columns = 1; 00218 Gutter = 0; 00219 00220 // Print output vars 00221 Layers = PRINTLAYERS_VISIBLEFOREGROUND; 00222 // Job 10463: remove PS Level bits - default to Level 2 00223 PSLangLevel = PSLEVEL_2; 00224 // PrintMethod = CurrentPrintMethod; 00225 BitmapResolutionMethod = BITMAPRES_AUTO; 00226 DotsPerInch = 150; 00227 FillQuality = PRINTFILLQUALITY_MEDIUM; 00228 TextOptions = PRINTTEXTOPTIONS_NORMAL; 00229 00230 // General print vars 00231 Collated = FALSE; 00232 NumCopies = 1; 00233 PrintToFile = FALSE; 00234 ObjPrintRange = PRINTRANGEOBJ_ALL; 00235 DPSPrintRange = PRINTRANGEDPS_BOTH; 00236 00237 // Misc 00238 UpdateDependants = TRUE; 00239 00240 // Print layout var initialisation 00241 Printing = FALSE; 00242 }; 00243 00244 /****************************************************************************************** 00245 00246 > PrintControl::~PrintControl() 00247 00248 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00249 Created: 27/3/95 00250 Inputs: - 00251 Outputs: - 00252 Returns: - 00253 Purpose: Default deconstructor 00254 Errors: - 00255 SeeAlso: PrintControl()::PrintControl() 00256 00257 ******************************************************************************************/ 00258 00259 PrintControl::~PrintControl() 00260 { 00261 // Does nowt as yet 00262 } 00263 00264 /****************************************************************************************** 00265 00266 > String_256 PrintControl::BuildPrintInfoStr() 00267 00268 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00269 Created: 7/4/95 00270 Inputs: - 00271 Outputs: - 00272 Returns: Returns the print info string 00273 Purpose: This uses the print control's settings to build the string displayed in the print info 00274 field of a print dlg 00275 Errors: - 00276 SeeAlso: - 00277 00278 ******************************************************************************************/ 00279 00280 String_256 PrintControl::BuildPrintInfoStr() 00281 { 00282 String_256 Str; 00283 00284 switch (FitType) 00285 { 00286 case PRINTFIT_BEST: Str = String_256(_R(IDS_PRINT_BESTFIT)); break; 00287 case PRINTFIT_CUSTOM: Str = String_256(_R(IDS_PRINT_CUSTOMFIT)); break; 00288 case PRINTFIT_MULTIPLE: Str = String_256(_R(IDS_PRINT_MULTIPLEFIT));break; 00289 case PRINTFIT_BESTPAPER:Str = String_256(_R(IDS_PRINT_BESTFITPAPER)); break; 00290 default: ERROR3_PF(("Unknown fit type (%d)",FitType)); break; 00291 } 00292 00293 TCHAR* format = _T("%.2lf%%"); 00294 double fScale = Scale.MakeDouble(); 00295 INT32 n = INT32((fScale*100)+0.5); 00296 00297 if (n % 100 == 0) 00298 format = _T("%.0lf%%"); 00299 else if (n % 10 == 0) 00300 format = _T("%.1lf%%"); 00301 00302 TCHAR s[100]; 00303 camSprintf(s,format,fScale); 00304 Str += s; 00305 00306 switch (Orient) 00307 { 00308 case PRINTORIENTATION_UPRIGHT: Str += String_256(_R(IDS_PRINT_UPRIGHT)); break; 00309 case PRINTORIENTATION_SIDEWAYS: Str += String_256(_R(IDS_PRINT_SIDEWAYS)); break; 00310 default: ERROR3_PF(("Unknown orientation (%d)",Orient)); break; 00311 } 00312 00313 // If no print area set up, then assume we have no printer connected 00314 if (!PrintAreaSetUp) 00315 { 00316 Str += String_256(_R(IDS_PRINT_NOPRINTER)); 00317 return Str; 00318 } 00319 00320 // Work out how many pages will get completely printed 00321 UINT32 NumPages = 1; 00322 UINT32 IDSPlural = _R(IDS_PRINT_PAGES); 00323 UINT32 IDSSingular = _R(IDS_PRINT_PAGE); 00324 00325 switch (FitType) 00326 { 00327 case PRINTFIT_BEST: 00328 case PRINTFIT_BESTPAPER: 00329 NumPages = 1; 00330 break; 00331 00332 case PRINTFIT_MULTIPLE: 00333 NumPages = 0; 00334 if (StartPrinting()) 00335 { 00336 GetNextPaper(); 00337 00338 PrintPatchInfo PatchInfo; 00339 while (GetNextPatch(&PatchInfo)) 00340 { 00341 DocRect Rect = PatchInfo.GetClipRect(FALSE,FALSE); 00342 double ScaleFactor = PatchInfo.Scale.MakeDouble() / 100; 00343 00344 INT32 w = Rect.Width(); 00345 INT32 h = Rect.Height(); 00346 00347 if (PatchInfo.Rotate) 00348 { INT32 t = w; w = h; h = t; } 00349 00350 Rect.lo.x = PatchInfo.XTrans; 00351 Rect.lo.y = PatchInfo.YTrans; 00352 00353 Rect.hi.x = Rect.lo.x + (INT32((double(w) * ScaleFactor)+0.5)); 00354 Rect.hi.y = Rect.lo.y + (INT32((double(h) * ScaleFactor)+0.5)); 00355 00356 if (PrintableArea.ContainsRect(Rect)) 00357 NumPages++; 00358 } 00359 00360 EndPrinting(); 00361 } 00362 IDSPlural = _R(IDS_PRINT_TILES); 00363 IDSSingular = _R(IDS_PRINT_TILE); 00364 break; 00365 00366 case PRINTFIT_CUSTOM: 00367 { 00368 DocRect Rect(0,PaperHeight-ScaledHeight,ScaledWidth,PaperHeight); 00369 00370 INT32 CropAdj = GetCropAdjust(); 00371 INT32 TransX = LeftMargin + CropAdj; 00372 INT32 TransY = TopMargin + CropAdj; 00373 00374 Rect.Translate(TransX,-TransY); 00375 if (PrintableArea.ContainsRect(Rect)) 00376 NumPages = 1; 00377 else 00378 NumPages = 0; 00379 } 00380 break; 00381 } 00382 00383 if (NumPages >= 1) 00384 { 00385 camSprintf(s, TEXT("%ld") ,NumPages); 00386 Str += s; 00387 00388 if (NumPages == 1) 00389 Str += String_256(IDSSingular); 00390 else 00391 Str += String_256(IDSPlural); 00392 } 00393 else 00394 Str += String_256(_R(IDS_PRINT_NOPAGESFIT)); 00395 00396 return Str; 00397 } 00398 00399 /****************************************************************************************** 00400 00401 > String_256 PrintControl::BuildPaperSizeStr() 00402 00403 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00404 Created: 7/4/95 00405 Inputs: - 00406 Outputs: - 00407 Returns: Returns the paper size string 00408 Purpose: This uses the printer settings to build the string displayed in the paper size 00409 field of a print options tab 00410 Errors: - 00411 SeeAlso: - 00412 00413 ******************************************************************************************/ 00414 00415 String_256 PrintControl::BuildPaperSizeStr() 00416 { 00417 String_256 Str = TEXT(""); 00418 String_256 TempStr = TEXT(""); 00419 00420 // If no print area set up, then assume we have no printer connected 00421 if (!PrintAreaSetUp) 00422 return Str; 00423 00424 DimScale* pDimScale = NULL; 00425 if (pSpread != NULL) 00426 pDimScale = DimScale::GetPtrDimScale(pSpread); 00427 00428 if (pDimScale != NULL) 00429 { 00430 BOOL ActiveState = pDimScale->IsActive(); 00431 pDimScale->SetActiveState(FALSE); 00432 00433 pDimScale->ConvertToUnits(PaperWidth,&TempStr); 00434 Str += TempStr; 00435 00436 Str += String_32(_R(IDS_NUM_BY_NUM)); 00437 00438 pDimScale->ConvertToUnits(PaperHeight,&TempStr); 00439 Str += TempStr; 00440 // WEBSTER-ranbirr-13/11/96 00441 #ifndef WEBSTER 00442 INT32 PrScale; 00443 if (CCPrintDialog::GetScale(&PrScale)) 00444 { 00445 if (PrScale != 100) 00446 { 00447 Str += String_256(_R(IDS_PRINT_PRINTERSCALING)); 00448 00449 TCHAR s[100]; 00450 String_32 jcf(_R(IDS_PERCENT_FORMAT)); 00451 camSprintf(s, jcf, (INT32) PrScale); 00452 Str += s; 00453 } 00454 } 00455 #endif //webster 00456 pDimScale->SetActiveState(ActiveState); 00457 } 00458 00459 return Str; 00460 } 00461 00462 /****************************************************************************************** 00463 00464 > PrintControl& PrintControl::operator=(PrintControl& other) 00465 00466 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00467 Created: 27/3/95 00468 Inputs: the object to copy 00469 Outputs: - 00470 Returns: ref to copy of other 00471 Purpose: The assignment operator for PrintControl 00472 Errors: - 00473 SeeAlso: - 00474 00475 ******************************************************************************************/ 00476 00477 PrintControl& PrintControl::operator=(PrintControl& other) 00478 { 00479 PrintAreaSetUp = other.PrintAreaSetUp; 00480 SetUpFailed = other.SetUpFailed; 00481 pSpread = other.pSpread; 00482 00483 TotalPrintArea = other.TotalPrintArea; 00484 PrintableArea = other.PrintableArea; 00485 PALeftMargin = other.PALeftMargin; 00486 PATopMargin = other.PATopMargin; 00487 00488 Origin = other.Origin; 00489 PaperWidth = other.PaperWidth; 00490 PaperHeight = other.PaperHeight; 00491 PageWidth = other.PageWidth; 00492 PageHeight = other.PageHeight; 00493 OrigPageWidth = other.OrigPageWidth; 00494 OrigPageHeight = other.OrigPageHeight; 00495 00496 // Print layout vars 00497 WholeSpread = other.WholeSpread; 00498 DPS = other.DPS; 00499 Bleed = other.Bleed; 00500 00501 CropArea = other.CropArea; 00502 CropTopMargin = other.CropTopMargin; 00503 CropLeftMargin = other.CropLeftMargin; 00504 00505 Scale = other.Scale; 00506 Orient = other.Orient; 00507 00508 FitType = other.FitType; 00509 00510 TopMargin = other.TopMargin; 00511 LeftMargin = other.LeftMargin; 00512 ScaledWidth = other.ScaledWidth; 00513 ScaledHeight= other.ScaledHeight; 00514 00515 Rows = other.Rows; 00516 Columns = other.Columns; 00517 Gutter = other.Gutter; 00518 00519 // Print output vars 00520 Layers = other.Layers; 00521 PSLangLevel = other.PSLangLevel; 00522 // PrintMethod = other.PrintMethod; 00523 BitmapResolutionMethod = other.BitmapResolutionMethod; 00524 DotsPerInch = other.DotsPerInch; 00525 FillQuality = other.FillQuality; 00526 TextOptions = other.TextOptions; 00527 00528 // General print vars 00529 Collated = other.Collated; 00530 NumCopies = other.NumCopies; 00531 PrintToFile = other.PrintToFile; 00532 ObjPrintRange = other.ObjPrintRange; 00533 DPSPrintRange = other.DPSPrintRange; 00534 00535 // The TypesetInfo 00536 Typesetting = other.Typesetting; 00537 00538 // Finally, make sure we have calculated all of the print settings like scaling properly 00539 if (pSpread != NULL) 00540 SetUp(pSpread); 00541 00542 return *this; 00543 }; 00544 00545 //------------------------------------------------ 00546 00547 /****************************************************************************************** 00548 00549 > BOOL PrintControl::SetUp(Spread* pThisSpread, BOOL RedrawPrintBorders = TRUE) 00550 00551 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00552 Created: 4/4/95 00553 Inputs: pThisSpread = ptr to a spread to print 00554 RedrawPrintBorders - True if want a force redraw of associated docs (Defaults to TRUE) 00555 Outputs: PrintAreaSetUp has same BOOL value as the return result 00556 Returns: TRUE if able to set up print area OR already set up 00557 Purpose: This function sets up the print control to print the given spread. 00558 00559 The entire spread area is used as the source area to print. It can determine from the spread 00560 whether it is a double page spread (DPS) or not. 00561 00562 Once it gets the source area for printing from the spread, it calcs the fit for the spread 00563 using the current fit type. I.e. it works out the scale factor and scaled page width 00564 and height for each page printed, given the current settings. 00565 00566 Errors: - 00567 SeeAlso: - 00568 00569 ******************************************************************************************/ 00570 00571 BOOL PrintControl::SetUp(Spread* pThisSpread, BOOL RedrawPrintBorders) 00572 { 00573 ERROR2IF(pThisSpread == NULL,FALSE,"pThisSpread is NULL"); 00574 00575 pSpread = pThisSpread; 00576 00577 // find out if it's a double page spread 00578 if (!pSpread->GetPageSize(NULL,NULL,NULL,&Bleed,&DPS,NULL)) 00579 return FALSE; 00580 00581 // Get a union of all the pages that represents the total printable area of the spread 00582 pSpread->GetPagesRect(&TotalPrintArea); 00583 00584 PrintAreaSetUp = (CalcPrintAreaVars(RedrawPrintBorders) && CalcFit()); 00585 SetUpFailed = !PrintAreaSetUp; 00586 00587 return PrintAreaSetUp; 00588 } 00589 00590 /****************************************************************************************** 00591 00592 > BOOL PrintControl::CalcPrintAreaVars(BOOL RedrawPrintBorders = TRUE) 00593 00594 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00595 Created: 11/4/95 00596 Inputs: RedrawPrintBorders - True if want a force redraw of associated docs (Defaults to TRUE) 00597 Outputs: - 00598 Returns: TRUE if able to recalc 00599 Purpose: This function calcs member vars dependant on the total print area. 00600 The print area can be set up using SetUp(). 00601 00602 Dependants are: 00603 PageWidth 00604 PageHeight 00605 Origin 00606 PrintableArea 00607 00608 It takes into account orientation, and whether its a double page spread (DPS). 00609 If it's a DPS, it also takes the WholeSpread setting into account 00610 00611 NOTE: This func also finds out the width and height of the printer's paper using 00612 CCPrintDialog::GetPaperSize(), and calcs the paper's area too 00613 00614 Errors: - 00615 SeeAlso: SetUp() 00616 00617 ******************************************************************************************/ 00618 00619 BOOL PrintControl::CalcPrintAreaVars(BOOL RedrawPrintBorders) 00620 { 00621 // Calc the print area origin 00622 Origin.x = TotalPrintArea.lo.x; 00623 Origin.y = TotalPrintArea.hi.y; 00624 00625 //------------------------- 00626 // Find out the dimensions of the printer's paper (in MILLIPOINTS) 00627 wxSize PaperSize; 00628 // WEBSTER-ranbirr-13/11/96 00629 #ifndef WEBSTER 00630 if (!CCPrintDialog::GetPaperSize(&PaperSize, RedrawPrintBorders)) 00631 return FALSE; 00632 #endif //webster 00633 PaperWidth = PaperSize.GetWidth(); 00634 PaperHeight = PaperSize.GetHeight(); 00635 00636 // ------------------------ 00637 // Get the printable area on the paper (defined relative to a origin at the bottom left of paper) 00638 // and the top & left margins of the printable area 00639 // WEBSTER-ranbirr-13/11/96 00640 #ifndef WEBSTER 00641 if (!CCPrintDialog::GetPrintableArea(&PrintableArea)) 00642 return FALSE; 00643 if (!CCPrintDialog::GetPrintMargins(&PALeftMargin,&PATopMargin)) 00644 return FALSE; 00645 #endif //webster 00646 //------------------------- 00647 // Calc the width and height of the print area 00648 PageWidth = TotalPrintArea.hi.x - TotalPrintArea.lo.x; 00649 PageHeight = TotalPrintArea.hi.y - TotalPrintArea.lo.y; 00650 00651 // If double page spread AND printing single pages, half the width for each page printed 00652 if (DPS && !WholeSpread) 00653 (PageWidth) /= 2; 00654 00655 // Save the orig values in case PageWidth & PageHeight need to be swapped due to sideways orientation 00656 OrigPageWidth = PageWidth; 00657 OrigPageHeight = PageHeight; 00658 00659 // If printing sideways, the width and height of the printed page should be swapped 00660 if (Orient == PRINTORIENTATION_SIDEWAYS) 00661 Swap(PageWidth,PageHeight); 00662 00663 return TRUE; 00664 } 00665 00666 /****************************************************************************************** 00667 00668 > void PrintControl::StartImport() 00669 00670 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00671 Created: 10/4/95 00672 Inputs: - 00673 Purpose: Tells the object that it's data is being imported. 00674 00675 In this state, calling the Set functions just sets the aspect of the object, 00676 rather than recalculation dependant aspects of the object. 00677 00678 e.g. calling SetScale() will recalc the width & height of the printed page 00679 unless you call StartImport() first 00680 00681 You can call this func any time, not just for importing, if you need to alter 00682 mmembers independently. 00683 00684 SeeAlso: EndImport() 00685 00686 ******************************************************************************************/ 00687 00688 void PrintControl::StartImport() 00689 { 00690 UpdateDependants = FALSE; 00691 } 00692 00693 /****************************************************************************************** 00694 00695 > void PrintControl::StartImport() 00696 00697 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00698 Created: 10/4/95 00699 Inputs: - 00700 Purpose: Tells the object that it's data is no longer being imported. 00701 SeeAlso: StartImport() 00702 00703 ******************************************************************************************/ 00704 00705 void PrintControl::EndImport() 00706 { 00707 UpdateDependants = TRUE; 00708 } 00709 00710 //------------------------- 00711 00712 00713 /****************************************************************************************** 00714 00715 > INT32 PrintControl::GetNumPrintablePages() 00716 00717 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00718 Created: 12/4/95 00719 Inputs: - 00720 Returns: Number of printable pages (1 or 2) 00721 Purpose: This tells you how many individual pages are printable, given the current settings 00722 00723 1 is returned: 00724 If it's not a DPS 00725 If it's a DPS, but we're printing the whole spread as one page 00726 If it's a DPS, we're printing individual pages, but the print range is either Left or Right-only 00727 00728 2 is returned: 00729 It's a DPS AND individual pages AND printing both pages 00730 00731 SeeAlso: - 00732 00733 ******************************************************************************************/ 00734 00735 INT32 PrintControl::GetNumPrintablePages() 00736 { 00737 if (DPS && !WholeSpread && (DPSPrintRange == PRINTRANGEDPS_BOTH)) 00738 return 2; 00739 else 00740 return 1; 00741 } 00742 00743 //------------------------- 00744 00745 /****************************************************************************************** 00746 00747 > void PrintControl::SetScaleFactor(double ScaleFactor) 00748 00749 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00750 Created: 10/4/95 00751 Inputs: ScaleFactor = the scale factor 00752 Purpose: Sets the scale percentage using the given scale factor 00753 This alters dependants automatically (unless importing) 00754 Dependants are: 00755 ScaledWidth 00756 ScaledHeight 00757 SeeAlso: StartImport() & EndImport() 00758 00759 ******************************************************************************************/ 00760 00761 void PrintControl::SetScaleFactor(double ScaleFactor) 00762 { 00763 SetScale(FIXED16(100*ScaleFactor)); 00764 } 00765 00766 /****************************************************************************************** 00767 00768 > void PrintControl::SetScale(FIXED16 NewScale) 00769 00770 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00771 Created: 10/4/95 00772 Inputs: NewScale = new scale factor 00773 Purpose: Sets the scale percentage, altering dependants automatically (unless importing) 00774 Dependants are: 00775 ScaledWidth 00776 ScaledHeight 00777 SeeAlso: StartImport() & EndImport() 00778 00779 ******************************************************************************************/ 00780 00781 void PrintControl::SetScale(FIXED16 NewScale) 00782 { 00783 Scale = NewScale; 00784 FIXED16 Min = FIXED16(MinPrintScale); 00785 FIXED16 Max = FIXED16(MaxPrintScale); 00786 00787 if (Scale < Min) Scale = Min; 00788 if (Scale > Max) Scale = Max; 00789 00790 if (UpdateDependants) 00791 { 00792 double ScaleFactor = (Scale.MakeDouble())/100; 00793 00794 ScaledWidth = INT32((double(PageWidth) *ScaleFactor)+0.5); 00795 ScaledHeight = INT32((double(PageHeight)*ScaleFactor)+0.5); 00796 } 00797 } 00798 00799 /****************************************************************************************** 00800 00801 > void PrintControl::SetPrintOrient(PrintOrient NewOrient) 00802 00803 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00804 Created: 10/4/95 00805 Inputs: NewOrient = new orientation 00806 Purpose: Sets the print orientatio, altering dependants automatically (unless importing) 00807 00808 Dependants are: 00809 ScaledWidth 00810 ScaledHeight 00811 PageWidth 00812 PageHeight 00813 Scale 00814 00815 and possibly: 00816 Rows 00817 Columns 00818 00819 SeeAlso: StartImport() & EndImport() 00820 00821 ******************************************************************************************/ 00822 00823 void PrintControl::SetPrintOrient(PrintOrient NewOrient) 00824 { 00825 if (Orient != NewOrient) 00826 { 00827 Orient = NewOrient; 00828 00829 if (UpdateDependants) 00830 { 00831 CalcPrintAreaVars(); // Update the page width and height (these get swapped) 00832 SetRows(Rows); // Use SetRows() to recalc max rows and scale factor 00833 SetColumns(Columns); // Use SetColumns() to recalc max columns and scale factor 00834 00835 // This is a bodge fix. Sometimes the gutter value can become -ve. In this case, 00836 // reset the multiple fit vars 00837 if (Gutter < 0) 00838 { 00839 SetRows(1); // Use SetRows() to recalc max rows and scale factor 00840 SetColumns(1); // Use SetColumns() to recalc max columns and scale factor 00841 SetGutter(0); 00842 } 00843 } 00844 } 00845 } 00846 00847 /****************************************************************************************** 00848 00849 > void PrintControl::SetWidth(INT32 NewVal) 00850 00851 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00852 Created: 10/4/95 00853 Inputs: NewVal = new width for the print area 00854 Purpose: Sets the page width, altering dependants automatically (unless importing) 00855 Dependants are: 00856 Scale 00857 ScaledHeight 00858 SeeAlso: StartImport() & EndImport() 00859 00860 ******************************************************************************************/ 00861 00862 void PrintControl::SetWidth(INT32 NewVal) 00863 { 00864 if (UpdateDependants) 00865 { 00866 double ScaleFactor = double(NewVal)/double(PageWidth); 00867 SetScaleFactor(ScaleFactor); // Use SetScaleFactor() to recalc ScaledWidth and ScaledHeight 00868 } 00869 else 00870 ScaledWidth = NewVal; 00871 } 00872 00873 00874 /****************************************************************************************** 00875 00876 > void PrintControl::SetHeight(INT32 NewVal) 00877 00878 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00879 Created: 10/4/95 00880 Inputs: NewVal = new height for the print area 00881 Purpose: Sets the page height, altering dependants automatically (unless importing) 00882 Dependants are: 00883 Scale 00884 ScaledWidth 00885 SeeAlso: StartImport() & EndImport() 00886 00887 ******************************************************************************************/ 00888 00889 void PrintControl::SetHeight(INT32 NewVal) 00890 { 00891 if (UpdateDependants) 00892 { 00893 double ScaleFactor = double(NewVal)/double(PageHeight); 00894 SetScaleFactor(ScaleFactor); // Use SetScaleFactor() to recalc ScaledWidth and ScaledHeight 00895 } 00896 else 00897 ScaledHeight = NewVal; 00898 } 00899 00900 //------------------------- 00901 //------------------------- 00902 //------------------------- 00903 00904 /****************************************************************************************** 00905 00906 > double PrintControl::CalcPatchWidth(INT32 Wd,INT32 NumColumns, INT32 GutterVal) 00907 00908 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00909 Created: 11/4/95 00910 Inputs: Wd = Width of paper 00911 NumColumns = number of columns down the paper 00912 Gutter = gutter distance between each page 00913 Returns: The width of each patch for multiple fit printing 00914 Purpose: The patch width = (width of the paper / num columns) - gutter 00915 SeeAlso: - 00916 00917 ******************************************************************************************/ 00918 00919 double PrintControl::CalcPatchWidth(INT32 Wd,INT32 NumColumns,INT32 GutterVal) 00920 { 00921 return ((double(Wd) / double(NumColumns)) - double(GutterVal)); 00922 } 00923 00924 /****************************************************************************************** 00925 00926 > double PrintControl::CalcPatchHeight(INT32 Ht,INT32 NumRows,INT32 GutterVal) 00927 00928 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00929 Created: 11/4/95 00930 Inputs: Ht = Height of paper 00931 NumRows = number of rows across the paper 00932 Gutter = gutter distance between each page 00933 Returns: The Height of each patch for multiple fit printing 00934 Purpose: The patch Height = (Height of the paper / num rows) - gutter 00935 SeeAlso: - 00936 00937 ******************************************************************************************/ 00938 00939 double PrintControl::CalcPatchHeight(INT32 Ht,INT32 NumRows,INT32 GutterVal) 00940 { 00941 return ((double(Ht) / double(NumRows)) - double(GutterVal)); 00942 } 00943 00944 /****************************************************************************************** 00945 00946 > INT32 PrintControl::CalcMaxRows(INT32 GutterVal) 00947 00948 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00949 Created: 11/4/95 00950 Inputs: GutterVal = the gutter value to use 00951 Returns: Max num rows for the current paper width and gutter setting 00952 Purpose: Dynamically calcs the max num rows possible, given the current paper width 00953 and gutter setting. 00954 00955 This is based on the min scale factor allowed 00956 SeeAlso: - 00957 00958 ******************************************************************************************/ 00959 00960 INT32 PrintControl::CalcMaxRows(INT32 GutterVal) 00961 { 00962 INT32 MaxRows = 0; 00963 double MinScaleFactor = double(MinPrintScale)/100; 00964 double PatchHeight,ScaleFactor; 00965 00966 do 00967 { 00968 MaxRows += 1; 00969 PatchHeight = CalcPatchHeight(PaperHeight,MaxRows,GutterVal); 00970 ScaleFactor = PatchHeight / PageHeight; 00971 } while (ScaleFactor >= MinScaleFactor); 00972 00973 if (MaxRows > 1) 00974 MaxRows -= 1; 00975 00976 return MaxRows; 00977 } 00978 00979 /****************************************************************************************** 00980 00981 > INT32 PrintControl::CalcMaxColumns(INT32 GutterVal) 00982 00983 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00984 Created: 11/4/95 00985 Inputs: GutterVal = the gutter value to use 00986 Returns: Max num columns for the current paper height and gutter setting 00987 Purpose: Dynamically calcs the max num columns possible, given the current paper height 00988 and gutter setting. 00989 00990 This is based on the min scale factor allowed 00991 SeeAlso: - 00992 00993 ******************************************************************************************/ 00994 00995 INT32 PrintControl::CalcMaxColumns(INT32 GutterVal) 00996 { 00997 INT32 MaxColumns = 0; 00998 double MinScaleFactor = double(MinPrintScale)/100; 00999 double PatchWidth,ScaleFactor; 01000 01001 do 01002 { 01003 MaxColumns += 1; 01004 PatchWidth = CalcPatchWidth(PaperWidth,MaxColumns,GutterVal); 01005 ScaleFactor = PatchWidth / PageWidth; 01006 } while (ScaleFactor >= MinScaleFactor); 01007 01008 if (MaxColumns > 1) 01009 MaxColumns -= 1; 01010 01011 return MaxColumns; 01012 } 01013 01014 /****************************************************************************************** 01015 01016 > INT32 PrintControl::CalcMaxGutter(INT32 NumRows,INT32 NumColumns) 01017 01018 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01019 Created: 11/4/95 01020 Inputs: NumRows = num rows to base calc on 01021 NumColumns = num columns to base calc on 01022 Returns: Max gutter value 01023 Purpose: Dynamically calcs the max gutter value based on the given number of rows and columns, 01024 and the current paper size 01025 SeeAlso: - 01026 01027 ******************************************************************************************/ 01028 01029 INT32 PrintControl::CalcMaxGutter(INT32 NumRows,INT32 NumColumns) 01030 { 01031 double MinScaleFactor = double(MinPrintScale)/100; 01032 01033 double PatchWidth = CalcPatchWidth(PaperWidth,NumColumns,0); 01034 double PatchHeight = CalcPatchHeight(PaperHeight,NumRows,0); 01035 01036 INT32 MaxGutterWidth = INT32((PatchWidth - (double(PageWidth) *MinScaleFactor))+0.5); 01037 INT32 MaxGutterHeight = INT32((PatchHeight - (double(PageHeight)*MinScaleFactor))+0.5); 01038 01039 if (MaxGutterWidth < MaxGutterHeight) 01040 return MaxGutterWidth; 01041 else 01042 return MaxGutterHeight; 01043 } 01044 01045 /****************************************************************************************** 01046 01047 > void PrintControl::CalcMultipleFit(INT32 NumRows,INT32 NumColumns,INT32 GutterVal,INT32 Wd,INT32 Ht) 01048 01049 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01050 Created: 11/4/95 01051 Inputs: NumRows = num rows to fit on paper 01052 NumColumns = num columns to fit on paper 01053 GutterVal = gutter distance between each page 01054 Wd = Width of paper 01055 Ht = Height of paper 01056 Extra = An adjustment made to the page size (usually 0) 01057 Returns: - 01058 Purpose: Recalcs the scale factor required for each page to fit the specified number of rows 01059 and columns, and gutter distance, to the paper 01060 01061 Dependants are: 01062 Scale 01063 ScaledWidth 01064 ScaledHeight 01065 01066 SeeAlso: StartImport() & EndImport() 01067 01068 ******************************************************************************************/ 01069 01070 void PrintControl::CalcMultipleFit(INT32 NumRows,INT32 NumColumns,INT32 GutterVal,INT32 Wd,INT32 Ht,INT32 Extra) 01071 { 01072 // Calc the width and height of each patch on the page, taking into account the given gutter value 01073 double PatchWidth = CalcPatchWidth(Wd,NumColumns,GutterVal); 01074 double PatchHeight = CalcPatchHeight(Ht,NumRows,GutterVal); 01075 01076 // Work out the scale factor required to get the width of the page into this patch 01077 double ScaleFactor = PatchWidth / double(PageWidth+Extra); 01078 01079 // Calc the new width and height of each page by applying the scale factor 01080 double NewWidth = PageWidth * ScaleFactor; 01081 double NewHeight= PageHeight * ScaleFactor; 01082 01083 // If the scale factor made using the page width and patch width means that the page does NOT entirely 01084 // fit into a multiple-fit patch, then use the scale factor generated using the patch height and page height 01085 // 01086 // (NB: We add 1.0 to these values so that the '>' comparisons don't fail due to insignificant floating point errors). 01087 // 01088 if ((NewWidth > (PatchWidth+1.0)) || (NewHeight > (PatchHeight+1.0))) 01089 ScaleFactor = PatchHeight / double(PageHeight+Extra); 01090 01091 #ifdef _DEBUG 01092 { 01093 // In theory, when the scale factor is applied to the page width and height, the page will fit 01094 // entirely into a patch. However, we still better check this is true when in debug builds 01095 01096 NewWidth = PageWidth * ScaleFactor; 01097 NewHeight= PageHeight * ScaleFactor; 01098 01099 if ((NewWidth > (PatchWidth+1.0)) || (NewHeight > (PatchHeight+1.0))) 01100 { 01101 ERROR3("Multiple fit scale factor does not fit page into patch"); 01102 } 01103 } 01104 #endif 01105 01106 SetScaleFactor(ScaleFactor); // Use SetScaleFactor() to recalc ScaledWidth and ScaledHeight 01107 } 01108 01109 /****************************************************************************************** 01110 01111 > BOOL PrintControl::CalcFit() 01112 01113 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01114 Created: 11/4/95 01115 Inputs: - 01116 Returns: TRUE if a recalc took place, FALSE if nothing has been recalced 01117 Purpose: Recalcs the scale factor needed to fit the current page in the specified 01118 orientation, using the currently set fit type 01119 01120 This will only do anything when UpdateDependants is TRUE 01121 01122 SeeAlso: CalcMultipleFit() 01123 01124 ******************************************************************************************/ 01125 01126 BOOL PrintControl::CalcFit() 01127 { 01128 static BOOL IgnoreCall = FALSE; 01129 01130 if (!UpdateDependants) 01131 return FALSE; 01132 01133 if (IgnoreCall) // Stop re-entrant calls to this function 01134 return TRUE; 01135 01136 IgnoreCall = TRUE; 01137 01138 // Set these value to absolutely ziltch 01139 CropTopMargin=0; 01140 CropLeftMargin=0; 01141 01142 switch (FitType) 01143 { 01144 case PRINTFIT_MULTIPLE: 01145 { 01146 INT32 PAWidth = PaperWidth; 01147 INT32 PAHeight = PaperHeight; 01148 01149 INT32 CropAdjust = GetCropAdjust(); 01150 01151 PAWidth -= (CropAdjust<<1); 01152 PAHeight -= (CropAdjust<<1); 01153 01154 CalcMultipleFit(Rows,Columns,Gutter,PAWidth,PAHeight,0); 01155 01156 // these settings just show to the user whats happening in the dialogue 01157 // they do not get used explicitly to position the pages. 01158 if ((Rows==1) && (Columns==1)) 01159 { 01160 LeftMargin = (PaperWidth -ScaledWidth) /2; 01161 TopMargin = (PaperHeight-ScaledHeight)/2; 01162 } 01163 } 01164 break; 01165 01166 case PRINTFIT_BEST: 01167 { 01168 INT32 PAWidth = PrintableArea.Width(); 01169 INT32 PAHeight = PrintableArea.Height(); 01170 01171 INT32 CropAdjust = GetCropAdjust(); 01172 01173 PAWidth -= (CropAdjust<<1); 01174 PAHeight -= (CropAdjust<<1); 01175 01176 BOOL PAOrient = ((double(PAWidth) / double(PAHeight)) <= 1.0); 01177 BOOL PageOrient = ((double(OrigPageWidth) / double(OrigPageHeight ))<= 1.0); 01178 01179 PrintOrient NewOrient; 01180 01181 if (PAOrient == PageOrient) 01182 NewOrient = PRINTORIENTATION_UPRIGHT; 01183 else 01184 NewOrient = PRINTORIENTATION_SIDEWAYS; 01185 01186 if (NewOrient != Orient) 01187 SetPrintOrient(NewOrient); 01188 01189 CalcMultipleFit(1,1,0,PAWidth,PAHeight,0); 01190 01191 PAWidth += (CropAdjust<<1); 01192 PAHeight += (CropAdjust<<1); 01193 01194 LeftMargin = PALeftMargin+((PAWidth -ScaledWidth) /2); 01195 TopMargin = PATopMargin +((PAHeight-ScaledHeight)/2); 01196 } 01197 break; 01198 01199 case PRINTFIT_CUSTOM: 01200 { 01201 INT32 CropAdjust = GetCropAdjust(); 01202 CropLeftMargin = CropAdjust; 01203 CropTopMargin = CropAdjust; 01204 SetScale(Scale); 01205 } 01206 break; 01207 01208 case PRINTFIT_BESTPAPER: 01209 // Best fit the document paper size onto the printed page 01210 // without scaling, distortion or clipping 01211 { 01212 INT32 PAWidth = PaperWidth; 01213 INT32 PAHeight = PaperHeight; 01214 01215 INT32 CropAdjust = GetCropAdjust(); 01216 01217 PAWidth -= (CropAdjust<<1); 01218 PAHeight -= (CropAdjust<<1); 01219 01220 // Compute aspect of document and aspect of printed page 01221 // TRUE means rect is portrait orientation, taller than it is wide... 01222 BOOL PAOrient = (double(PAWidth) <= double(PAHeight)); 01223 BOOL PageOrient = (double(OrigPageWidth) <= double(OrigPageHeight)); 01224 01225 PrintOrient NewOrient; 01226 01227 if (PAOrient == PageOrient) 01228 NewOrient = PRINTORIENTATION_UPRIGHT; 01229 else 01230 NewOrient = PRINTORIENTATION_SIDEWAYS; 01231 01232 if (NewOrient != Orient) 01233 SetPrintOrient(NewOrient); 01234 01235 CropLeftMargin = CropAdjust; 01236 CropTopMargin = CropAdjust; 01237 SetScale(100.0); 01238 01239 // PAWidth += (CropAdjust<<1); 01240 // PAHeight += (CropAdjust<<1); 01241 01242 // Centre document page within printed page 01243 LeftMargin = (PAWidth - ScaledWidth) / 2; 01244 TopMargin = (PAHeight - ScaledHeight) / 2; 01245 } 01246 break; 01247 01248 default: 01249 ERROR3_PF(("Unknown fit type (%d)",FitType)); 01250 IgnoreCall = FALSE; 01251 return FALSE; 01252 } 01253 01254 IgnoreCall = FALSE; 01255 01256 return TRUE; 01257 } 01258 01259 /****************************************************************************************** 01260 01261 > INT32 PrintControl::GetCropAdjust() const 01262 01263 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01264 Created: 16/12/96 01265 Inputs: - 01266 Returns: An INT32, the width of the crop area 01267 Purpose: Return the size of the extra area we need to take into account when fitting 01268 pages onto the printable paper. Currently the bleed size and crop area size 01269 is used. 01270 01271 ******************************************************************************************/ 01272 01273 INT32 PrintControl::GetCropAdjust() const 01274 { 01275 INT32 CropAdjust = 0; 01276 01277 PrintMarksMan *pMarksMan = GetApplication()->GetMarksManager(); 01278 if (pMarksMan && Typesetting.OutputPrintersMarks()) 01279 CropAdjust = CropArea+Bleed; 01280 01281 return CropAdjust; 01282 } 01283 01284 01285 /****************************************************************************************** 01286 01287 > void PrintControl::AdjustForTypesetting() 01288 01289 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01290 Created: 16/12/96 01291 Inputs: - 01292 Returns: - 01293 Purpose: Adjust the printing variables to allow for typesetting marks to be positioned 01294 What happens here is that we adjust the X,Y translations so that we ensure 01295 a patch is moved into a position where we can get the crop marks between the 01296 patch and the papers edges. 01297 01298 ******************************************************************************************/ 01299 01300 /* 01301 void PrintControl::AdjustForTypesetting() 01302 { 01303 // Used to do it like this but don't anymore. 01304 01305 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 01306 #ifndef STANDALONE 01307 PrintMarksMan *pMarksMan = GetApplication()->GetMarksManager(); 01308 if (pMarksMan && GetTypesetInfo()->OutputPrintersMarks()) 01309 { 01310 switch (FitType) 01311 { 01312 case PRINTFIT_MULTIPLE: 01313 { 01314 CropTopMargin = CropArea; 01315 CropLeftMargin = CropArea; 01316 // if the bleed is more than 1/2 of the gutter, then the 01317 // bleed will overflow the edge of the page by the difference! 01318 double sectw = CalcPatchWidth( PaperWidth, Columns,0); 01319 double secth = CalcPatchHeight(PaperHeight,Rows ,0); 01320 // Translate to the bottom left of the current patch 01321 double ovflx = Bleed - ((sectw - (double)ScaledWidth)/2); 01322 double ovfly = Bleed - ((secth - (double)ScaledHeight)/2); 01323 01324 CropLeftMargin += (INT32)(ovflx+0.5); 01325 CropTopMargin += (INT32)(ovfly+0.5); 01326 } 01327 break; 01328 01329 case PRINTFIT_BEST: 01330 { 01331 // does nothing at the moment. 01332 } 01333 break; 01334 01335 case PRINTFIT_CUSTOM: 01336 { 01337 CropLeftMargin = CropArea+Bleed; 01338 CropTopMargin = CropArea+Bleed; 01339 } 01340 break; 01341 01342 default: 01343 ERROR3_PF(("Unknown fit type (%d)",FitType)); 01344 break; 01345 } 01346 } 01347 #endif 01348 #endif 01349 } 01350 */ 01351 01352 01353 /****************************************************************************************** 01354 01355 > BOOL PrintControl::SetRows(INT32 NewVal) 01356 01357 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01358 Created: 10/4/95 01359 Inputs: NewVal = new number of coloumns of printed pages 01360 Returns: TRUE if new row num == NewVal, FALSE if it's had to be altered because NewVal is out of range 01361 Purpose: Sets the number of pages in each printed column, altering dependants automatically (unless importing) 01362 Dependants are: 01363 Scale 01364 ScaledWidth 01365 ScaledHeight 01366 Columns 01367 01368 If not updating dependants, this will always return TRUE 01369 01370 SeeAlso: StartImport() & EndImport() 01371 01372 ******************************************************************************************/ 01373 01374 BOOL PrintControl::SetRows(INT32 NewVal) 01375 { 01376 Rows = NewVal; 01377 01378 if (UpdateDependants) 01379 { 01380 INT32 Max = CalcMaxRows(0); 01381 01382 if (Rows < 1) Rows = 1; 01383 if (Rows > Max) Rows = Max; 01384 01385 INT32 MaxGutter = CalcMaxGutter(Rows,Columns); 01386 if (Gutter > MaxGutter) 01387 Gutter = MaxGutter; 01388 01389 CalcFit(); 01390 } 01391 01392 return (Rows == NewVal); 01393 } 01394 01395 /****************************************************************************************** 01396 01397 > BOOL PrintControl::SetColumns(INT32 NewVal) 01398 01399 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01400 Created: 10/4/95 01401 Inputs: NewVal = new number of coloumns of printed pages 01402 Returns: TRUE if new row num == NewVal, FALSE if it's had to be altered because NewVal is out of range 01403 Purpose: Sets the number of pages in each printed column, altering dependants automatically (unless importing) 01404 Dependants are: 01405 Scale 01406 ScaledWidth 01407 ScaledHeight 01408 Rows 01409 01410 If not updating dependants, this will always return TRUE 01411 01412 SeeAlso: StartImport() & EndImport() 01413 01414 ******************************************************************************************/ 01415 01416 BOOL PrintControl::SetColumns(INT32 NewVal) 01417 { 01418 Columns = NewVal; 01419 01420 if (UpdateDependants) 01421 { 01422 INT32 Max = CalcMaxColumns(0); 01423 01424 if (Columns < 1) Columns = 1; 01425 if (Columns > Max) Columns = Max; 01426 01427 INT32 MaxGutter = CalcMaxGutter(Rows,Columns); 01428 if (Gutter > MaxGutter) 01429 Gutter = MaxGutter; 01430 01431 CalcFit(); 01432 } 01433 01434 return (Columns == NewVal); 01435 } 01436 01437 /****************************************************************************************** 01438 01439 > BOOL PrintControl::SetGutter(INT32 NewVal) 01440 01441 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01442 Created: 10/4/95 01443 Inputs: NewVal = new gutter measurement between each page 01444 Returns: TRUE if new row num == NewVal, FALSE if it's had to be altered because NewVal is out of range 01445 Purpose: Sets the gutter measurement, altering dependants automatically (unless importing) 01446 01447 The gutter is the distance between each page when doing multiple fit printing. 01448 Half the gutter width is used as a margin for each page next to the edge of the paper 01449 01450 Dependants are: 01451 Scale 01452 ScaledWidth 01453 ScaledHeight 01454 Rows 01455 Colunmns 01456 01457 If not updating dependants, this will always return TRUE 01458 01459 SeeAlso: StartImport() & EndImport() 01460 01461 ******************************************************************************************/ 01462 01463 BOOL PrintControl::SetGutter(INT32 NewVal) 01464 { 01465 Gutter = NewVal; 01466 01467 if (UpdateDependants) 01468 { 01469 INT32 Max = CalcMaxGutter(1,1); 01470 01471 if (Gutter < 0) Gutter = 0; 01472 if (Gutter > Max) Gutter = Max; 01473 01474 INT32 MaxRows = CalcMaxRows(Gutter); 01475 if (Rows > MaxRows) 01476 Rows = MaxRows; 01477 01478 INT32 MaxColumns = CalcMaxColumns(Gutter); 01479 if (Columns > MaxColumns) 01480 Columns = MaxColumns; 01481 01482 CalcFit(); 01483 } 01484 01485 return (Gutter == NewVal); 01486 } 01487 01488 /****************************************************************************************** 01489 01490 > void PrintControl::SetWholeSpread(BOOL State) 01491 01492 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01493 Created: 11/4/95 01494 Inputs: State = new WholeSpread flag state 01495 Purpose: Sets the WholeSpread state, altering dependants automatically (unless importing) 01496 01497 Dependants are: 01498 Scale 01499 ScaledWidth 01500 ScaledHeight 01501 PageWidth 01502 PageHeight 01503 Rows 01504 Columns 01505 SeeAlso: StartImport() & EndImport() 01506 01507 ******************************************************************************************/ 01508 01509 void PrintControl::SetWholeSpread(BOOL State) 01510 { 01511 if (WholeSpread != State) 01512 { 01513 WholeSpread = State; 01514 01515 if (UpdateDependants) 01516 { 01517 CalcPrintAreaVars(); // Update the page width & height (the page width either doubles or halves) 01518 SetRows(Rows); // Use SetRows() to recalc max rows and scale factor 01519 SetColumns(Columns); // Use SetColumns() to recalc max columns and scale factor 01520 } 01521 } 01522 } 01523 01524 /****************************************************************************************** 01525 01526 > void PrintControl::SetFitType(PrintFitType NewFitType) 01527 01528 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01529 Created: 11/4/95 01530 Inputs: NewFitType = page fit type 01531 Purpose: Sets the fit type, altering dependants automatically (unless importing) 01532 01533 Dependants are: 01534 ScaledWidth 01535 ScaledHeight 01536 Scale 01537 SeeAlso: StartImport() & EndImport() 01538 01539 ******************************************************************************************/ 01540 01541 void PrintControl::SetFitType(PrintFitType NewFitType) 01542 { 01543 FitType = NewFitType; 01544 01545 if (UpdateDependants) 01546 CalcFit(); 01547 } 01548 01549 /****************************************************************************************** 01550 01551 > INT32 PrintControl::GetDotsPerInch() 01552 01553 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01554 Created: 18/4/95 01555 Inputs: - 01556 Returns: DPI value used to render bitmaps 01557 Purpose: If the bitmap res setting is manual then the value the user entered is returned. 01558 If the bitmap res setting is automatic, then base the DPI on the printer's DPI 01559 01560 Bitmap res = Half printer res 01561 01562 if (Bitmap res > MAXAUTOBITMAPDPI) 01563 Bitmap res = MAXAUTOBITMAPDPI; 01564 01565 if (Bitmap res < MINBITMAPDPI) 01566 Bitmap res = MINBITMAPDPI; 01567 01568 SeeAlso: SetDotsPerInch(); 01569 01570 ******************************************************************************************/ 01571 01572 INT32 PrintControl::GetDotsPerInch() 01573 { 01574 // MRH 11/9/00 - Tidied up code to make it more readable 01575 // Basically the code checks to see if the auto flag is set. 01576 // If NOT set then the DotsPerInch variable is left with the value in the manual edit box. 01577 // If it is set then it gets the current printer resolution and divides it by 2! 01578 if (BitmapResolutionMethod == BITMAPRES_AUTO) 01579 { 01580 // Choose the DPI automatically 01581 // This is based on the printer resolution 01582 // Set up the local variable to the max auto dpi! 01583 INT32 PrinterDPI = MAXAUTOBITMAPDPI; 01584 01585 // Get the printer resolution (if this fails, choose the maximum setting) 01586 if (!CCPrintDialog::GetResolution(&PrinterDPI)) 01587 PrinterDPI = MAXAUTOBITMAPDPI; // Failing could change the variable so reset it! 01588 01589 // Make the DPI half the printer res 01590 DotsPerInch = PrinterDPI >> 1; 01591 01592 // If this DPI value > MAXAUTOBITMAPDPI, then probably printing to a typesetter, in which case cap it as 01593 // there's no point in printing at any higher DPI 01594 if (DotsPerInch > MAXAUTOBITMAPDPI) 01595 DotsPerInch = MAXAUTOBITMAPDPI; 01596 01597 // Make sure that it doesn't dip below the min. 01598 // If it does, choose the printer DPI, so that we ensure good quality for low DPI settings 01599 if (DotsPerInch < MINBITMAPDPI) 01600 DotsPerInch = PrinterDPI; 01601 } 01602 01603 // return the new value! 01604 return DotsPerInch; 01605 } 01606 01607 01608 /****************************************************************************************** 01609 01610 > void PrintControl::SetDotsPerInch(INT32 NewVal) 01611 01612 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01613 Created: 18/4/95 01614 Inputs: NewVal = DPI value 01615 Returns: - 01616 Purpose: Ensures the NewVal is not < MINBITMAPDPI 01617 01618 If NewVal < MINBITMAP, the DPI is set to the printer's DPI 01619 01620 SeeAlso: GetDotsPerInch() 01621 01622 ******************************************************************************************/ 01623 01624 void PrintControl::SetDotsPerInch(INT32 NewVal) 01625 { 01626 DotsPerInch = NewVal; 01627 01628 if (DotsPerInch > MAXBITMAPDPI) 01629 DotsPerInch = MAXBITMAPDPI; 01630 01631 if (DotsPerInch < MINBITMAPDPI) 01632 DotsPerInch = MINBITMAPDPI; 01633 01634 /* 01635 if (DotsPerInch < MINBITMAPDPI) 01636 { 01637 INT32 PrinterDPI; 01638 01639 // Get the printer resolution (if this fails, choose the minimum setting) 01640 if (!CCPrintDialog::GetResolution(&PrinterDPI)) 01641 PrinterDPI = MINBITMAPDPI; 01642 01643 DotsPerInch = PrinterDPI; 01644 } 01645 */ 01646 } 01647 01648 /****************************************************************************************** 01649 01650 > PrintMethodType PrintControl::GetPrintMethod(PrintMethodType NewVal) 01651 01652 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01653 Created: 20/7/95 01654 Inputs: - 01655 Returns: The app's current print method 01656 Purpose: Returns the app's print method. 01657 This is stored in the global var AppPrintMethod 01658 01659 SeeAlso: SetPrintMethod() 01660 01661 ******************************************************************************************/ 01662 01663 PrintMethodType PrintControl::GetPrintMethod() 01664 { 01665 return AppPrintMethod; 01666 } 01667 01668 /****************************************************************************************** 01669 01670 > void PrintControl::SetPrintMethod(PrintMethodType NewVal) 01671 01672 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01673 Created: 20/7/95 01674 Inputs: NewVal = new print method 01675 Returns: - 01676 Purpose: Sets the app's print method to be NewVal 01677 This is stored in the global var AppPrintMethod 01678 01679 SeeAlso: GetPrintMethod() 01680 01681 ******************************************************************************************/ 01682 01683 void PrintControl::SetPrintMethod(PrintMethodType NewVal) 01684 { 01685 AppPrintMethod = NewVal; 01686 } 01687 01688 /****************************************************************************************** 01689 01690 > void PrintControl::GetObjPrintRange() 01691 01692 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01693 Created: 22/7/96 01694 Inputs: - 01695 Returns: PRINTRANGEOBJ_ALL or PRINTRANGEOBJ_SELECTED 01696 Purpose: Find out the object range the user wants to print to. 01697 01698 This function has been modified (today 22/7/96) so that it reacts to the current selection. 01699 This is to fix bug 4857, which meant if you selected "print selected objects" then 01700 deselected all the objects, it would still print the selected objects, resulting in a 01701 blank page. 01702 01703 What's worse, the UI in the print dlg would grey out, so you couldn't switch it off. 01704 01705 This routine will mean that "print all" is on if the internal var is PRINTRANGEOBJ_ALL 01706 OR there are no selected objects. 01707 01708 SeeAlso: GetPrintMethod() 01709 01710 ******************************************************************************************/ 01711 01712 PrintRangeObj PrintControl::GetObjPrintRange() 01713 { 01714 // Find the selection 01715 SelRange* pSelRange = GetApplication()->FindSelection(); 01716 01717 if (pSelRange->FindFirst() != NULL) 01718 return ObjPrintRange; // There are selected objects, so return the setting the user has made. 01719 else 01720 return PRINTRANGEOBJ_ALL; // There's no selected objects, so always print all objects. 01721 } 01722 01723 //-------------------------------------------------------------------------- 01724 // Print layout funcs 01725 01726 /****************************************************************************************** 01727 01728 > BOOL PrintControl::CalcNumPaper() 01729 01730 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01731 Created: 18/4/95 01732 Inputs: - 01733 Outputs: NumPaper = The number of pieces of paper we will print to 01734 Returns: TRUE if it was able to cal num paper to print to, FALSE otherwise 01735 01736 Purpose: This works out how many pieces of paper we will print to. 01737 NB: This can be different to the number of pieces of paper that comes out of the printer 01738 when the printer can do multiple copies and we are in a position to exploit this 01739 01740 It takes into account DPS, whole spread & left or right-only settings. 01741 It also takes into account the collated flag & the ability of the printer 01742 to do multiple copies. 01743 01744 The number of pieces of paper that the printer will produce at the end of the print job 01745 = number of printable pages * num copies 01746 01747 If the output is colla 01748 01749 SeeAlso: GetDotsPerInch() 01750 01751 ******************************************************************************************/ 01752 01753 BOOL PrintControl::CalcNumPaper() 01754 { 01755 BOOL CanMultiCopy=TRUE; 01756 // WEBSTER-ranbirr-13/11/96 01757 #ifndef WEBSTER 01758 // Can the printer do multiple copies? 01759 if (!CCPrintDialog::CanMultiCopy(&CanMultiCopy)) 01760 return FALSE; 01761 #endif //webster 01762 INT32 NumActualPiecesOfPaper = NumPrintablePages * NumCopies; // Num pieces of paper that will come out of printer 01763 01764 // NumPaper will be the number of pieces of paper we will print to 01765 // Default to the number printable of pages 01766 NumPaper = NumPrintablePages; 01767 01768 if (NumPrintablePages == 1) 01769 { 01770 // If the printer can't cope with multiple copies, we'll have to do them all 01771 if (!CanMultiCopy) 01772 NumPaper = NumActualPiecesOfPaper; 01773 } 01774 else 01775 { 01776 // If the printer can't cope with multiple copies OR we need to collate the output 01777 // we'll have to do them all 01778 if (Collated || !CanMultiCopy) 01779 NumPaper = NumActualPiecesOfPaper; 01780 } 01781 01782 return TRUE; 01783 } 01784 01785 /******************************************************************************************** 01786 01787 > BOOL PrintControl::StartPrinting() 01788 01789 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01790 Created: 25/4/95 01791 Inputs: - 01792 Returns: TRUE if all OK, FALSE otherwise 01793 Purpose: This informs the print info object that you are about to do some printing. 01794 01795 This is purely to set up the print layout mechanism. It will work out how many 01796 pieces of paper will be printed to, and how many times the page will be printed 01797 on each piece of of paper (for multiple fit printing). 01798 01799 The mechanism works like this: 01800 01801 if (StartPrinting()) 01802 { 01803 while (GetNextPaper()) 01804 { 01805 while (GetNextPatch()) 01806 { 01807 Use access funcs to get hold of data set up by GetNextPath(), e.g. scale, translation, etc 01808 01809 if (SelectedOnly) 01810 print all selected objects that lie within the ClipRect area in the spread 01811 else 01812 print all objects that lie within the ClipRect area in the spread 01813 } 01814 } 01815 01816 EndPrinting() 01817 } 01818 01819 SeeAlso: GetNextPaper(), GetNextPath(), EndPrinting() 01820 01821 ********************************************************************************************/ 01822 01823 BOOL PrintControl::StartPrinting() 01824 { 01825 ERROR2IF(Printing,FALSE,"Already printing - have you called EndPrinting()?"); 01826 ERROR2IF(!PrintAreaSetUp,FALSE,"The print control hasn't been set up via SetUp()"); 01827 ERROR2IF(pSpread == NULL,FALSE,"The print control pSpread is NULL"); 01828 01829 // Find out the number of printable pages 01830 NumPrintablePages = GetNumPrintablePages(); // This will be either 1 or 2 01831 01832 // Init NumPaper member var with the number of pieces of paper we will print to. 01833 if (!CalcNumPaper()) 01834 return FALSE; 01835 01836 // PaperNumber is the number of the current piece of paper being printed to. 01837 // MaxPaperNumber is the total number of pieces of paper we will print to. 01838 PaperNumber = 0; // incremented at the start of GetNextPaper() 01839 MaxPaperNumber = NumPaper; 01840 Reprint = FALSE; // Set to TRUE by ReprintPaper() to make GetNextPaper() to return 01841 // the same paper again 01842 01843 NumPatches = 0; 01844 Printing = TRUE; 01845 01846 SelRange* pSelRange = GetApplication()->FindSelection(); 01847 SelectionPresent = (pSelRange->FindFirst() != NULL); 01848 01849 // Now make sure that the list of printing plates is updated in case any spot colours 01850 // have been created or deleted recently... 01851 TypesetInfo* tpInfo = GetTypesetInfo(); 01852 if (tpInfo != NULL && tpInfo->AreSeparating()) 01853 { 01854 // Call CreatePlateList to ensure that the list of printing plates is set up 01855 // This will just update the list (if necessary) if it has been previously created, 01856 // to make sure that screening options and present plates are all hunky-dory. 01857 tpInfo->CreatePlateList(); 01858 } 01859 01860 return TRUE; 01861 } 01862 01863 01864 01865 01866 /******************************************************************************************** 01867 01868 > BOOL PrintControl::EndPrinting() 01869 01870 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01871 Created: 26/4/95 01872 Inputs: - 01873 Returns: TRUE if all OK, FALSE otherwise 01874 Purpose: This informs the print info object that you have finished printing. 01875 SeeAlso: StartPrinting(); 01876 01877 ********************************************************************************************/ 01878 01879 BOOL PrintControl::EndPrinting() 01880 { 01881 ERROR2IF(!Printing,FALSE,"Not printing - have you called StartPrinting()?"); 01882 Printing = FALSE; 01883 return TRUE; 01884 } 01885 01886 01887 01888 01889 01890 /******************************************************************************************** 01891 01892 > BOOL PrintControl::GetNextPaper() 01893 01894 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01895 Created: 26/4/95 01896 Inputs: - 01897 Returns: TRUE if you should print on another piece of paper 01898 FALSE if the print job should end 01899 Purpose: Call this for each piece of paper to be printed to. 01900 NB: You must call StartPrinting() before calling this func as part of your print loop 01901 01902 If ReprintPaper() is called after GetNextPaper(), then the next time you call 01903 GetNextPaper() you will actually be printing the previous piece of paper 01904 e.g 01905 while (GetNextPaper()) // Infinite loop 01906 ReprintPaper(); 01907 01908 01909 SeeAlso: StartPrinting(),EndPrinting(), ReprintPaper() 01910 01911 ********************************************************************************************/ 01912 01913 BOOL PrintControl::GetNextPaper() 01914 { 01915 ERROR2IF(!Printing,FALSE,"Not printing - have you called StartPrinting()?"); 01916 01917 // Do we need to reprint the same piece of paper? 01918 if (Reprint) 01919 { 01920 // Only re-jig the counters if we have called GetNextPaper() at least once 01921 if (NumPaper < MaxPaperNumber) 01922 { 01923 NumPaper++; 01924 PaperNumber--; 01925 } 01926 // Reprinting, so set flag to FALSE 01927 Reprint = FALSE; 01928 } 01929 01930 if (NumPaper > 0) 01931 { 01932 NumPaper--; 01933 PaperNumber++; 01934 01935 // Calc the number of patches we'll have to print on this next piece of paper 01936 if (FitType == PRINTFIT_MULTIPLE) 01937 { 01938 NumPatches = Rows*Columns; 01939 01940 // PatchRow & PatchColumn form a coordinate specifying which patch to print next 01941 PatchRow = 0; 01942 PatchColumn = 0; 01943 01944 // Section width and height define the size of the areas of the page patches will fit into. 01945 // Effectively these are the patch sizes ignoring the gutter value. 01946 // Each patch is centred within a section of the page. 01947 INT32 CropAdjust = GetCropAdjust(); 01948 INT32 PAWidth = PaperWidth - (CropAdjust<<1); 01949 INT32 PAHeight = PaperHeight - (CropAdjust<<1); 01950 SectionWidth = INT32(CalcPatchWidth(PAWidth, Columns,0)); 01951 SectionHeight = INT32(CalcPatchHeight(PAHeight,Rows, 0)); 01952 } 01953 else 01954 NumPatches = 1; 01955 01956 // PatchNumber is the number of the current patch being printed to. 01957 // MaxPatchNumber is the total number of patches printed on this piece of paper 01958 PatchNumber = 0; // incremented at the start of GetNextPatch() 01959 MaxPatchNumber = NumPatches; 01960 01961 // Calc the object clip rect used to define which objects within the total printable area should 01962 // be printed on this piece of paper 01963 // 01964 // Default to the total printable area 01965 PatchClipRect = TotalPrintArea; 01966 01967 if (NumPrintablePages > 1) 01968 { 01969 // The number of printable pages > 1 (i.e. we have a double page spread, we are printing 01970 // both left & right pages, and printing individual pages) 01971 01972 INT32 m; 01973 01974 if (Collated) 01975 { 01976 // If collated output, then oscillate the clip rect 01977 // between the left and right page, controlled by the current paper number 01978 m = (PaperNumber-1) % NumPrintablePages; 01979 } 01980 else 01981 { 01982 // Otherwise, print 'n' left pages followed by 'n' right pages 01983 m = (PaperNumber-1) / (MaxPaperNumber / NumPrintablePages); 01984 } 01985 01986 PatchClipRect.lo.x += (OrigPageWidth*m); 01987 PatchClipRect.hi.x = PatchClipRect.lo.x + OrigPageWidth; 01988 } 01989 else 01990 { 01991 if (DPS && !WholeSpread && (DPSPrintRange != PRINTRANGEDPS_BOTH)) 01992 { 01993 // Here we have a DPS, we are printing individual pages, but we are either 01994 // printing left-only or right-only pages 01995 // 01996 // So if right only, add the page width to the lo.x coord to move the area to the right hand side. 01997 // In either case, the patch clip rect hi.x will be lo.x+OrigPageWidth. 01998 01999 if (DPSPrintRange == PRINTRANGEDPS_RIGHTPAGES) 02000 PatchClipRect.lo.x += OrigPageWidth; 02001 02002 PatchClipRect.hi.x = PatchClipRect.lo.x + OrigPageWidth; 02003 } 02004 } 02005 02006 // take into account the bleed margin 02007 /* 02008 PatchClipRect.Inflate(Bleed); 02009 if (Orient == PRINTORIENTATION_SIDEWAYS) 02010 PatchClipRect.Translate(-Bleed,Bleed); 02011 else 02012 PatchClipRect.Translate(Bleed,Bleed); 02013 */ 02014 return TRUE; 02015 } 02016 02017 return FALSE; 02018 } 02019 02020 02021 02022 /******************************************************************************************** 02023 02024 > BOOL PrintControl::MorePaper() 02025 02026 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02027 Created: 11/6/96 02028 Inputs: - 02029 Returns: TRUE if there is more paper to come 02030 FALSE if there's no more paper. 02031 Purpose: Call this for each piece of paper to be printed to. 02032 02033 ********************************************************************************************/ 02034 02035 BOOL PrintControl::MorePaper() 02036 { 02037 if (Reprint && NumPaper < MaxPaperNumber) 02038 return TRUE; 02039 02040 return (NumPaper > 0); 02041 } 02042 02043 02044 /******************************************************************************************** 02045 02046 > BOOL PrintControl::ReprintPaper() 02047 02048 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02049 Created: 26/4/95 02050 Inputs: - 02051 Returns: TRUE if all OK, FALSE otherwise 02052 Purpose: This allows you to print on the same piece of paper again. 02053 02054 If you call this func after a call to GetNextPaper(), then the next time you 02055 call GetNextPaper() you will actually be starting the print on the same piece of 02056 paper. 02057 02058 SeeAlso: GetNextPaper() 02059 02060 ********************************************************************************************/ 02061 02062 BOOL PrintControl::ReprintPaper() 02063 { 02064 Reprint = TRUE; 02065 return TRUE; 02066 } 02067 02068 /******************************************************************************************** 02069 02070 > BOOL PrintControl::GetNextPatch(PrintPatchInfo* pPatchInfo) 02071 02072 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02073 Created: 26/4/95 02074 Inputs: pPatchInfo = ptr to object to store patch info in 02075 Outputs: - 02076 Returns: TRUE if you should print another page on the paper 02077 FALSE if the piece of paper printed to is finished. 02078 Purpose: Each time this func returns TRUE, print the page using the data set up by this call. 02079 02080 If this call returns TRUE, the the given PrintPatchInfo has been set up with 02081 all the data needed to print the given patch. 02082 02083 NB: You must call GetNextPaper() before calling this func as part of your print loop 02084 02085 SeeAlso: StartPrinting(), GetNextPaper(), EndPrinting() 02086 02087 ********************************************************************************************/ 02088 02089 BOOL PrintControl::GetNextPatch(PrintPatchInfo* pPatchInfo) 02090 { 02091 ERROR2IF(!Printing,FALSE,"Not printing - have you called StartPrinting()?"); 02092 ERROR2IF(pPatchInfo == NULL,FALSE,"Given NULL pPatchInfo param"); 02093 02094 if (NumPatches > 0) 02095 { 02096 NumPatches--; 02097 PatchNumber++; 02098 02099 pPatchInfo->pSpread = pSpread; 02100 pPatchInfo->Scale = Scale; 02101 pPatchInfo->ClipRect = PatchClipRect; 02102 pPatchInfo->Rotate = (Orient == PRINTORIENTATION_SIDEWAYS); 02103 pPatchInfo->SelectedOnly = ((ObjPrintRange == PRINTRANGEOBJ_SELECTED) && SelectionPresent); 02104 pPatchInfo->VisibleLayers = (Layers == PRINTLAYERS_VISIBLEFOREGROUND); 02105 pPatchInfo->XTrans = 0; 02106 pPatchInfo->YTrans = 0; 02107 pPatchInfo->PaperWidth = PaperWidth; 02108 pPatchInfo->PaperHeight = PaperHeight; 02109 pPatchInfo->ScaledWidth = ScaledWidth; 02110 pPatchInfo->ScaledHeight = ScaledHeight; 02111 pPatchInfo->Bleed = Bleed; 02112 pPatchInfo->CropArea = CropArea; 02113 pPatchInfo->PaperNumber = PaperNumber; 02114 pPatchInfo->MaxPaperNumber = MaxPaperNumber; 02115 pPatchInfo->PatchNumber = PatchNumber; 02116 pPatchInfo->MaxPatchNumber = MaxPatchNumber; 02117 pPatchInfo->PALeftMargin = PALeftMargin; 02118 pPatchInfo->PATopMargin = PATopMargin; 02119 02120 // set emulsion up/down for print rendering 02121 TypesetInfo* tpInfo = GetTypesetInfo(); 02122 pPatchInfo->EmulsionDown = ( (tpInfo != NULL) && tpInfo->PrintEmulsionDown() ); 02123 02124 switch (FitType) 02125 { 02126 case PRINTFIT_BEST: 02127 // Move it to the right by LeftMargin, and down by TopMargin 02128 pPatchInfo->XTrans = LeftMargin; 02129 pPatchInfo->YTrans = (PaperHeight-ScaledHeight)-TopMargin; 02130 break; 02131 02132 case PRINTFIT_BESTPAPER: 02133 // Move it to the right by LeftMargin, and down by TopMargin 02134 pPatchInfo->XTrans = LeftMargin; 02135 pPatchInfo->YTrans = (PaperHeight-ScaledHeight)-TopMargin; 02136 pPatchInfo->XTrans += CropLeftMargin; 02137 pPatchInfo->YTrans -= CropTopMargin; 02138 break; 02139 02140 case PRINTFIT_CUSTOM: 02141 { 02142 // Move it to the right by LeftMargin, and down by TopMargin 02143 pPatchInfo->XTrans = LeftMargin; 02144 pPatchInfo->YTrans = (PaperHeight-ScaledHeight)-TopMargin; 02145 pPatchInfo->XTrans += CropLeftMargin; 02146 pPatchInfo->YTrans -= CropTopMargin; 02147 } 02148 break; 02149 02150 case PRINTFIT_MULTIPLE: 02151 { 02152 // Translate to the bottom left of the current patch 02153 INT32 CropAdjust = GetCropAdjust(); 02154 02155 pPatchInfo->XTrans = CropAdjust + (SectionWidth * PatchColumn) + ((SectionWidth - ScaledWidth)/2); 02156 pPatchInfo->YTrans = CropAdjust + (SectionHeight * PatchRow) + ((SectionHeight - ScaledHeight)/2); 02157 02158 PatchColumn += 1; 02159 if (PatchColumn >= Columns) 02160 { 02161 PatchColumn = 0; 02162 PatchRow += 1; 02163 } 02164 } 02165 break; 02166 02167 default: 02168 ERROR3_PF(("Unknown fit type : %d",FitType)); 02169 break; 02170 } 02171 02172 return TRUE; 02173 } 02174 02175 return FALSE; 02176 } 02177 02178 02179 02180 02181 /******************************************************************************************** 02182 02183 > BOOL PrintControl::StartPlatePrinting(PrintView *pPrintView, UINT32 *const pErrNo) 02184 02185 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02186 Created: 11/6/96 02187 Inputs: pPrintView - The View to which we are rendering 02188 Outputs: errno - 02189 Returns: - 02190 Purpose: This function makes sure the plate printing loop is initialised for the 02191 next set of pages on a single sheet of paper to pass through the driver. 02192 It sets up an appropriate ColourPlate and ColourCOntextCMYK for the 02193 given PrintView. 02194 02195 ********************************************************************************************/ 02196 02197 BOOL PrintControl::StartPlatePrinting(PrintView *pPrintView, UINT32 *const pErrNo) 02198 { 02199 // Clear the ouput error first 02200 (*pErrNo)=0; 02201 02202 // If there's no view, drawing will be rather tricky 02203 if (pPrintView == NULL) 02204 { 02205 ERROR3("Sanity check, The view is NULL during StartPlatePrinting!"); 02206 return FALSE; 02207 } 02208 02209 // Get hold of the resident colour management system 02210 ColourContext *pContext; 02211 02212 PORTNOTE("cms", "Disabled XaraCMS"); 02213 #ifndef EXCLUDE_FROM_XARALX 02214 XaraCMS* ptheCMS=GetApplication()->GetCMSManager(); 02215 if (ptheCMS!=NULL) 02216 { 02217 // First try to set the printer context specified in the ini file read 02218 // when we started up 02219 String_256 PrintProfile; 02220 ptheCMS->GetPrinterProfile(&PrintProfile); 02221 pContext = new ColourContextCMYK(pPrintView, &PrintProfile); 02222 02223 if (pContext==NULL) 02224 { 02225 // We need to error here and inform the user we 02226 // are out of memory 02227 ERROR3("Failed to create a CMYK colour context during print initialisation in SetNextPlate()"); 02228 (*pErrNo) = _R(IDS_OUT_OF_MEMORY); 02229 return FALSE; 02230 } 02231 02232 if (!(pContext->IsDeviceContext())) 02233 { 02234 // Eeek, we failed to build the physical device context 02235 // which means something rather nasty went on. We must now 02236 // warn the user. They can either continue with a logical 02237 // context or abort the proceedings. 02238 02239 // TO DO: Make this a nice resourced string! 02240 // Hang about, we should attempt to use a printer.xcms down 02241 // the root directory of Camelot, lets see if we can find that 02242 02243 delete pContext; 02244 pContext=NULL; 02245 02246 ptheCMS->GetDefaultPrinterProfile(&PrintProfile); 02247 pContext = new ColourContextCMYK(pPrintView, &PrintProfile); 02248 02249 // if we've failed again 02250 if (pContext==NULL) 02251 { 02252 ERROR3("Failed to create a CMYK colour context during print initialisation in SetNextPlate()"); 02253 (*pErrNo) = _R(IDS_OUT_OF_MEMORY); 02254 return FALSE; 02255 } 02256 02257 // ok if we've still failed to locate even this we really are stuck and will have to use the context 02258 // in logical mode, but lets ask the user about this first. 02259 if (!(pContext->IsDeviceContext())) 02260 { 02261 ErrorInfo Info; 02262 Info.ErrorMsg = _R(IDT_OPTS_LOGICALCONTEXT); 02263 Info.Button[0] = _R(IDS_CONTINUE); 02264 Info.Button[1] = _R(IDS_CANCEL); 02265 if (AskQuestion(&Info) == _R(IDS_CANCEL)) 02266 { 02267 (*pErrNo) = _R(IDS_PRINT_USERTERM); 02268 return FALSE; 02269 } 02270 } 02271 } 02272 } 02273 else 02274 #endif 02275 { 02276 // Create a logical colour context. This isn't strictly necessary, as the view will default to 02277 // using the global default (logical) context anyway, but we might as well be safe 02278 pContext = new ColourContextCMYK(pPrintView); 02279 if (pContext==NULL) 02280 { 02281 // we've failed to create a new colour context for this document 02282 // We must abort the printing loop 02283 ERROR3("Failed to create a CMYK colour context during print initialisation in SetNextPlate()"); 02284 (*pErrNo) = _R(IDS_OUT_OF_MEMORY); 02285 return FALSE; 02286 } 02287 } 02288 02289 // Set the new context in the view. The view will delete it when it's done with it 02290 // NOTE that the view will attach its own ColourPlate to this context, so there is no need 02291 // (indeed, no point whatsoever) for us to try to set that up for it. 02292 pPrintView->SetColourContext(COLOURMODEL_CMYK, pContext); 02293 02294 // Set up the plate printing system, we do this for composite and separated output 02295 Typesetting.InitPlatesForPrinting(); 02296 02297 return TRUE; 02298 } 02299 02300 02301 02302 /******************************************************************************************** 02303 02304 > void PrintControl::EndPlatePrinting(PrintView *pPrintView) 02305 02306 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02307 Created: 11/6/96 02308 Inputs: - 02309 Returns: - 02310 Purpose: This function makes sure the plate printing loop is shut down correctly. 02311 We need to make sure that the last plate is detached from the colour context 02312 inside the print view, otherwise when the print view is destroyed the plate 02313 in the colour context in the print view will be destroyed. As our printer 02314 dialogue keeps this in its list, we need to make sure it only gets deleted 02315 once during that lists destruction. 02316 02317 ********************************************************************************************/ 02318 02319 void PrintControl::EndPlatePrinting(PrintView *pPrintView) 02320 { 02321 // If there's no view, drawing will be rather tricky 02322 if (pPrintView == NULL) 02323 { 02324 ERROR3("Sanity check, The view is NULL during StartPlatePrinting!"); 02325 return; 02326 } 02327 02328 pPrintView->SetColourContext(COLOURMODEL_CMYK, NULL); 02329 } 02330 02331 02332 02333 /******************************************************************************************** 02334 02335 > BOOL PrintControl::MorePlates() 02336 02337 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02338 Created: 11/6/96 02339 Inputs: - 02340 Returns: TRUE if there is more plates to come 02341 FALSE if there's no more plates. 02342 Purpose: Call this to determin whether there are more plates to print during this 02343 separation. 02344 02345 ********************************************************************************************/ 02346 02347 BOOL PrintControl::MorePlates() 02348 { 02349 return (Typesetting.NumPrintPlatesRemaining() > 0); 02350 } 02351 02352 02353 /******************************************************************************************** 02354 02355 > void PrintControl::SetNextPlate(PrintView *pPrintView) 02356 02357 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02358 Created: 11/6/96 02359 Inputs: pPrintView = a pointer to the print view class. 02360 Returns: - 02361 Purpose: Call this to set up the view related data ready for the next plate rendering 02362 02363 ********************************************************************************************/ 02364 02365 BOOL PrintControl::SetNextPlate(PrintView *pPrintView) 02366 { 02367 // If there's no view, drawing will be rather tricky 02368 if (pPrintView == NULL) 02369 { 02370 ERROR3("Sanity check, The view is NULL during SetNextPlate!"); 02371 return FALSE; 02372 } 02373 02374 // If we are not separating then do nothing but make sure 02375 // we force MorePlates() to terminate properly the next time 02376 // around. 02377 if (!Typesetting.AreSeparating()) 02378 { 02379 Typesetting.SetNextCompositePlate(); 02380 return TRUE; 02381 } 02382 02383 // Find the next printing plate. We need to call this to decrement 02384 // the plate printing count and other such unsightlyness so that MorePlates 02385 // executes correctly. 02386 ColourPlate *pPrintPlate = Typesetting.GetNextPrintPlate(); 02387 if (pPrintPlate==NULL) 02388 { 02389 // There are no more plates left to print. MorePlates() has 02390 // failed in its duty and should be shot. 02391 return FALSE; 02392 } 02393 02394 // We now need to set this plate in the print view in order 02395 // to describe the separation correctly, this should be pretty easy 02396 // if we can get a hold of the print view of course. 02397 pPrintView->SetColourPlate(pPrintPlate); 02398 02399 return TRUE; 02400 } 02401 02402 02403 02404 02405 /******************************************************************************************** 02406 02407 > void PrintControl::RenderRect(RenderRegion* pRRegion,DocRect Rect,BOOL Fill) 02408 02409 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02410 Created: 9/5/95 02411 Inputs: pRRegion = ptr to a render region 02412 Rect = rect to redraw 02413 Fill = TRUE if filled, FALSE if empty 02414 Outputs: - 02415 Returns: - 02416 Purpose: Renders the rect given 02417 SeeAlso: RenderPrintBorders() 02418 02419 ********************************************************************************************/ 02420 02421 void PrintControl::RenderRect(RenderRegion* pRRegion,DocRect Rect,BOOL Fill) 02422 { 02423 if (Rect.IsValid() && !Rect.IsEmpty()) 02424 { 02425 if (Fill) 02426 pRRegion->DrawRect(&Rect); 02427 else 02428 pRRegion->DrawPixelRect(&Rect); 02429 } 02430 } 02431 02432 /******************************************************************************************** 02433 02434 > void PrintControl::RenderPrintBorder(RenderRegion* pRRegion) 02435 02436 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02437 Created: 26/4/95 02438 Inputs: pRRegion = ptr to a render region 02439 Outputs: - 02440 Returns: - 02441 Purpose: Renders the printable area on the spread according to the current print layout method. 02442 SeeAlso: StartPrinting(), GetNextPaper(), EndPrinting() 02443 Note: As we are being given a render region that may be in the background redraw list, 02444 forcing a redraw of documents is very bad as this **MAY** delete the render region 02445 we hae been given. This used to happen if setup hadn't been called before when 02446 routine was entered for the first time. 02447 02448 ********************************************************************************************/ 02449 02450 void PrintControl::RenderPrintBorder(RenderRegion* pRRegion) 02451 { 02452 if (SetUpFailed) 02453 return; 02454 02455 BOOL DrawBorders = FALSE; 02456 02457 switch (FitType) 02458 { 02459 // Always try and show print borders for these fit types 02460 case PRINTFIT_BEST: 02461 case PRINTFIT_BESTPAPER: 02462 case PRINTFIT_CUSTOM: 02463 DrawBorders = TRUE; 02464 break; 02465 02466 // Only try and show print borders for multiple fit when doing 1 row by 1 column 02467 case PRINTFIT_MULTIPLE: 02468 DrawBorders = ((Rows == 1) && (Columns == 1)); 02469 break; 02470 02471 default: 02472 ERROR3_PF(("Unknown fit type (%d)",FitType)); 02473 break; 02474 } 02475 02476 // If we can draw borders for this fit type, ensure that the relevent info is available to do so 02477 if (DrawBorders) 02478 { 02479 // Neville 29/8/97 02480 // As we are being passed a render region and so might be in the background redraw 02481 // loop, we must not force a redraw of the doc if we haven't called set up before. 02482 // If we do then this render region may be deleted and we wont get told about it. 02483 // This is bad! e.g. Load document with print borders set and have a font replacement 02484 // message go off. 02485 if (!PrintAreaSetUp) 02486 DrawBorders = SetUp(Document::GetSelectedSpread(), FALSE); 02487 else 02488 DrawBorders = SetUp(pSpread, FALSE); 02489 } 02490 02491 // If the fit type is right, and we have all the info, draw the borders 02492 if (DrawBorders) 02493 { 02494 double ScaleFactor = 100.0 / Scale.MakeDouble(); 02495 02496 INT32 ScaledPaperWidth = INT32(double(PaperWidth) *ScaleFactor); 02497 INT32 ScaledPaperHeight = INT32(double(PaperHeight)*ScaleFactor); 02498 INT32 ScaledPAWidth = INT32(double(PrintableArea.Width()) *ScaleFactor); 02499 INT32 ScaledPAHeight = INT32(double(PrintableArea.Height())*ScaleFactor); 02500 INT32 ScaledPALeftMargin = INT32(double(PALeftMargin)*ScaleFactor); 02501 INT32 ScaledPATopMargin = INT32(double(PATopMargin) *ScaleFactor); 02502 INT32 ScaledLeftMargin = INT32(double(LeftMargin) *ScaleFactor)+CropLeftMargin; 02503 INT32 ScaledTopMargin = INT32(double(TopMargin) *ScaleFactor)+CropTopMargin; 02504 02505 INT32 StartPageNum = 0; // We're starting from page 0 (the left page) by default 02506 INT32 NumPages = GetNumPrintablePages(); // Find out how many we need to print 02507 02508 // If we're only printing the right page, then start from page 1 (the right page) 02509 // and increment the number of pages by 1 (i.e. the loop terminating value) 02510 // This will make sure that the print borders get drawn over the right page 02511 if ((NumPages == 1) && (DPSPrintRange == PRINTRANGEDPS_RIGHTPAGES)) 02512 { 02513 StartPageNum = 1; 02514 NumPages++; 02515 } 02516 02517 for (INT32 PageNum = StartPageNum;PageNum < NumPages;PageNum++) 02518 { 02519 StockColour PaperCol = COLOUR_YELLOW; 02520 StockColour PrAreaCol = COLOUR_RED; 02521 02522 if (PageNum > 0) 02523 { 02524 PaperCol = COLOUR_GREEN; 02525 PrAreaCol = COLOUR_BLUE; 02526 } 02527 02528 // PagePrintArea defines the portion of the spread that is printable (this 02529 // is either the whole spread, or a single page when printing DPS & individual pages) 02530 DocRect PagePrintArea = TotalPrintArea; 02531 PagePrintArea.lo.x += OrigPageWidth*PageNum; 02532 PagePrintArea.hi.x = PagePrintArea.lo.x + OrigPageWidth; 02533 PagePrintArea.hi.y = PagePrintArea.lo.y + OrigPageHeight; 02534 02535 // PrbleArea will define the printable area in relation to the current spread 02536 DocRect PrbleArea = PagePrintArea; 02537 02538 // PaperArea represents the total area of the paper in the printer 02539 DocRect PaperArea; 02540 02541 // If printing sideways, the width and height of the printable area should be swapped 02542 if (Orient == PRINTORIENTATION_SIDEWAYS) 02543 { 02544 PrbleArea.hi.x = PrbleArea.lo.x+ScaledPAHeight; 02545 PrbleArea.hi.y = PrbleArea.lo.y+ScaledPAWidth; 02546 PrbleArea.Translate(ScaledPATopMargin,ScaledPALeftMargin); 02547 PrbleArea.Translate(-ScaledTopMargin,-ScaledLeftMargin); 02548 02549 PaperArea = PrbleArea; 02550 PaperArea.Translate(-ScaledPATopMargin,-ScaledPALeftMargin); 02551 PaperArea.hi.x = PaperArea.lo.x + ScaledPaperHeight; 02552 PaperArea.hi.y = PaperArea.lo.y + ScaledPaperWidth; 02553 } 02554 else 02555 { 02556 PrbleArea.hi.x = PrbleArea.lo.x+ScaledPAWidth; 02557 PrbleArea.lo.y = PrbleArea.hi.y-ScaledPAHeight; 02558 PrbleArea.Translate(ScaledPALeftMargin,-ScaledPATopMargin); 02559 PrbleArea.Translate(-ScaledLeftMargin,ScaledTopMargin); 02560 02561 PaperArea = PrbleArea; 02562 PaperArea.Translate(-ScaledPALeftMargin,ScaledPATopMargin); 02563 PaperArea.hi.x = PaperArea.lo.x + ScaledPaperWidth; 02564 PaperArea.lo.y = PaperArea.hi.y - ScaledPaperHeight; 02565 } 02566 02567 // We need to draw four grey slabs that show the areas on the page that will 02568 // not be printed 02569 02570 pRRegion->SetLineColour(COLOUR_NONE); 02571 pRRegion->SetFillColour(COLOUR_MIDGREY); 02572 02573 DocRect Slab = PagePrintArea; 02574 Slab.hi.x = PrbleArea.lo.x; 02575 RenderRect(pRRegion,Slab,TRUE); 02576 02577 Slab = PagePrintArea; 02578 Slab.lo.x = PrbleArea.hi.x; 02579 RenderRect(pRRegion,Slab,TRUE); 02580 02581 Slab = PagePrintArea; 02582 Slab.hi.y = PrbleArea.lo.y; 02583 RenderRect(pRRegion,Slab,TRUE); 02584 02585 Slab = PagePrintArea; 02586 Slab.lo.y = PrbleArea.hi.y; 02587 RenderRect(pRRegion,Slab,TRUE); 02588 02589 pRRegion->SetFillColour(COLOUR_BLACK); 02590 RenderRect(pRRegion,PagePrintArea,FALSE); 02591 02592 pRRegion->SetFillColour(PrAreaCol); 02593 RenderRect(pRRegion,PrbleArea,FALSE); 02594 02595 pRRegion->SetFillColour(PaperCol); 02596 RenderRect(pRRegion,PaperArea,FALSE); 02597 } 02598 } 02599 } 02600 02601 /******************************************************************************************** 02602 02603 > BOOL PrintControl::RedrawPrintableArea(DocView* pDocView) 02604 02605 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02606 Created: 10/5/95 02607 Inputs: pDocView - ptr to DocView to redraw 02608 Outputs: - 02609 Returns: - 02610 Purpose: This func can be passed as a param to Document::ForceRedraw() and hence can control 02611 which views get redraw. 02612 This func ensures that only views that are showing print borders get redrawn. 02613 SeeAlso: StartPrinting(), GetNextPaper(), EndPrinting() 02614 02615 ********************************************************************************************/ 02616 02617 BOOL PrintControl::RedrawPrintableArea(DocView* pDocView) 02618 { 02619 if (pDocView->GetShowPrintBorders()) 02620 return(TRUE); 02621 02622 ColourPlateType PlateType = COLOURPLATE_NONE; 02623 if (pDocView->GetColourPlate() && !pDocView->GetColourPlate()->IsDisabled()) 02624 PlateType = pDocView->GetColourPlate()->GetType(); 02625 02626 return(PlateType != COLOURPLATE_NONE && PlateType != COLOURPLATE_COMPOSITE); 02627 } 02628 02629 02630 //------------------------------------------------------------ 02631 //------------------------------------------------------------ 02632 //------------------------------------------------------------ 02633 02634 /****************************************************************************************** 02635 02636 > PrintPatchInfo::PrintPatchInfo() 02637 02638 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02639 Created: 26/4/95 02640 Inputs: - 02641 Outputs: - 02642 Returns: - 02643 Purpose: Default constructor 02644 Errors: - 02645 SeeAlso: - 02646 02647 ******************************************************************************************/ 02648 02649 PrintPatchInfo::PrintPatchInfo() 02650 { 02651 Scale = FIXED16(100); 02652 XTrans = 0; 02653 YTrans = 0; 02654 ClipRect = DocRect(0,0,0,0); 02655 Rotate = FALSE; 02656 SelectedOnly = FALSE; 02657 EmulsionDown = FALSE; 02658 VisibleLayers = TRUE; 02659 pSpread = NULL; 02660 PaperWidth = 0; 02661 PaperHeight = 0; 02662 02663 02664 PaperNumber = 0; 02665 MaxPaperNumber = 0; 02666 PatchNumber = 0; 02667 MaxPatchNumber = 0; 02668 }; 02669 02670 /****************************************************************************************** 02671 02672 > PrintPatchInfo::~PrintPatchInfo() 02673 02674 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02675 Created: 26/4/95 02676 Inputs: - 02677 Outputs: - 02678 Returns: - 02679 Purpose: Default deconstructor 02680 Errors: - 02681 SeeAlso: PrintPatchInfo()::PrintPatchInfo() 02682 02683 ******************************************************************************************/ 02684 02685 PrintPatchInfo::~PrintPatchInfo() 02686 { 02687 // Does nowt as yet 02688 } 02689 02690 02691 /****************************************************************************************** 02692 02693 > DocRect PrintPatchInfo::GetClipRect(BOOL AddBleed, BOOL AddCropArea) 02694 02695 Author : Mike 02696 Created : 11/6/95 02697 Inputs : AddBleed = Inflate the output clip rectangle by the bleed value 02698 AddCropArea = Inflate the output clip rectangle by the crop area 02699 Returns : A clip rectangle. 02700 Purpose : Return the value of the clip rectangle held in this structure. The clip 02701 rectangle is defined to fit snuggly around a page. No other inflations 02702 should or do occur around this clip rectangle. However the printing mechanism 02703 needs to know about bleed sizes and cropmark areas in order to render 02704 and clip objects correctly so it uses inflated rectangles on occasions. 02705 It should not and cannot inflate rectangles itself however because this 02706 would assume knowledge of patch positioning which only the printcontrol 02707 class knows anything about. 02708 02709 ******************************************************************************************/ 02710 02711 DocRect PrintPatchInfo::GetClipRect(BOOL AddBleed, BOOL AddCropArea) const 02712 { 02713 DocRect Temp = ClipRect; 02714 InflateRectBy(&Temp, AddBleed, AddCropArea); 02715 return Temp; 02716 } 02717 02718 void PrintPatchInfo::InflateRectBy(DocRect *pRect, BOOL AddBleed, BOOL AddCropArea) const 02719 { 02720 if (AddBleed) 02721 pRect->Inflate(Bleed); 02722 if (AddCropArea) 02723 pRect->Inflate(CropArea); 02724 } 02725 02726 void PrintPatchInfo::InflateRectBy(OilRect *pRect, BOOL AddBleed, BOOL AddCropArea) const 02727 { 02728 if (AddBleed) 02729 pRect->Inflate(Bleed); 02730 if (AddCropArea) 02731 pRect->Inflate(CropArea); 02732 } 02733 02734 void PrintPatchInfo::DeflateRectBy(DocRect *pRect, BOOL AddBleed, BOOL AddCropArea) const 02735 { 02736 if (AddBleed) 02737 pRect->Inflate(-Bleed); 02738 if (AddCropArea) 02739 pRect->Inflate(-CropArea); 02740 } 02741 02742 MILLIPOINT PrintPatchInfo::GetBleed() const 02743 { 02744 return Bleed; 02745 } 02746 02747 MILLIPOINT PrintPatchInfo::GetCropArea() const 02748 { 02749 return CropArea; 02750 } 02751 02752 02753 02754 /****************************************************************************************** 02755 02756 > TypesetInfo::TypesetInfo() 02757 02758 Author : Mike 02759 Created : 11/6/95 02760 Purpose : The default constructor for the typesetting class. We use this class to 02761 define the typesetting requirements of the next print run. 02762 02763 ******************************************************************************************/ 02764 02765 TypesetInfo::TypesetInfo() 02766 { 02767 MakeSeparations = FALSE; 02768 02769 PrintResolution = 300; 02770 02771 ScreenFrequency = 60.0; 02772 DefaultScreenType = SCRTYPE_SPOT1; 02773 02774 UseScreening = FALSE; 02775 ShowPrintersMarks = FALSE; 02776 02777 EmulsionDown = FALSE; 02778 PhotoNegative = FALSE; 02779 OverprintBlack = FALSE; 02780 02781 NumPrintPlates = 0; 02782 CurrPrintPlateNum = 0; 02783 CurrentPlate = NULL; 02784 CurrentPrintPlate = NULL; 02785 } 02786 02787 02788 02789 /****************************************************************************************** 02790 02791 > TypesetInfo::~TypesetInfo() 02792 02793 Author : Mike 02794 Created : 11/6/95 02795 Purpose : The destructor. We must remove all items from our PrintingPlates list 02796 and delete them, otherwise the base list class will complain profusely. 02797 02798 ******************************************************************************************/ 02799 02800 TypesetInfo::~TypesetInfo() 02801 { 02802 DestroyPlateList(); 02803 } 02804 02805 02806 /****************************************************************************************** 02807 02808 > static TypesetInfo *TypesetInfo::FindTypesetInfoForDoc(Document *pDoc = NULL); 02809 02810 Author : Jason 02811 Created : 15/8/96 02812 Inputs : pDoc = NULL (to look in selected doc) or the document to find the info for 02813 Returns : NULL, or the selected doc's TypesetInfo 02814 Purpose : Conveniently find the typeset info for the given document 02815 02816 ******************************************************************************************/ 02817 02818 TypesetInfo *TypesetInfo::FindTypesetInfoForDoc(Document *pDoc) 02819 { 02820 if (pDoc == NULL) 02821 pDoc = Document::GetSelected(); 02822 02823 ERROR2IF(pDoc == NULL, NULL, "No document to find typeset info for!"); 02824 02825 // Find the doc's print component 02826 PrintComponent *pPrComp = (PrintComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(PrintComponent)); 02827 ERROR2IF(pPrComp == NULL, NULL, "Can't find a document's print component"); 02828 02829 // Find a ptr to the print component's print control object 02830 PrintControl* pPrCtrl = pPrComp->GetPrintControl(); 02831 ERROR2IF(pPrCtrl == NULL, NULL, "The doc's print component gave me a NULL print control object"); 02832 02833 TypesetInfo *pTInfo = pPrCtrl->GetTypesetInfo(); 02834 ERROR2IF(pTInfo == NULL, NULL, "The doc's print control object gave me a NULL TypesetInfo object"); 02835 02836 return(pTInfo); 02837 } 02838 02839 02840 02841 /****************************************************************************************** 02842 02843 > TypesetInfo& TypesetInfo::operator=(TypesetInfo& other) 02844 02845 Author : Jason 02846 Created : 17/9/96 02847 02848 Inputs : other - the TypesetInfo object to copy 02849 Returns : the copy (this) 02850 02851 Purpose : TypesetInfo assignment operator 02852 02853 ******************************************************************************************/ 02854 02855 TypesetInfo& TypesetInfo::operator=(TypesetInfo& other) 02856 { 02857 MakeSeparations = other.MakeSeparations; 02858 PrintResolution = other.PrintResolution; 02859 ScreenFrequency = other.ScreenFrequency; 02860 DefaultScreenType = other.DefaultScreenType; 02861 02862 UseScreening = other.UseScreening; 02863 02864 ShowPrintersMarks = other.ShowPrintersMarks; 02865 02866 EmulsionDown = other.EmulsionDown; 02867 PhotoNegative = other.PhotoNegative; 02868 OverprintBlack = other.OverprintBlack; 02869 PrintSpotAsProcess = other.PrintSpotAsProcess; 02870 02871 // Now copy the plate list 02872 // First, vape all pointers to default values 02873 CurrPrintPlateNum = 0; 02874 CurrentPlate = NULL; 02875 CurrentPrintPlate = NULL; 02876 02877 // Now destroy any plates we may have already 02878 DestroyPlateList(); 02879 02880 ColourPlate *pPlate = other.GetFirstPlate(); 02881 while (pPlate != NULL) 02882 { 02883 ColourPlate *pNewPlate = new ColourPlate(*pPlate); 02884 02885 if (pNewPlate == NULL) 02886 break; 02887 02888 AddPlate(pNewPlate); 02889 pPlate = other.GetNextPlate(pPlate); 02890 } 02891 02892 return(*this); 02893 } 02894 02895 02896 02897 /****************************************************************************************** 02898 02899 > BOOL TypesetInfo::GetScreenName(ScreenType type, StringBase *pString) 02900 02901 Author : Mike 02902 Created : 31/08/96 02903 Inputs : type = the type of screen to find the name for 02904 Returns : TRUE if the type is known 02905 FALSE if the type is unknown - pString will contain the default SPOT name 02906 Purpose : Conveniently convert from a screen type to a textual name 02907 02908 ******************************************************************************************/ 02909 02910 BOOL TypesetInfo::GetScreenName(ScreenType type, StringBase *pString) 02911 { 02912 ERROR2IF(pString==NULL, FALSE, "NULL output string pointer passed to GetScreenName"); 02913 02914 String_256 Str; 02915 BOOL known=TRUE; 02916 02917 switch (type) 02918 { 02919 case SCRTYPE_SPOT2: 02920 Str.Load(_R(IDS_SCRTYPE_SPOT2)); 02921 break; 02922 case SCRTYPE_TRIPLESPOT1: 02923 Str.Load(_R(IDS_SCRTYPE_TRIPLESPOT1)); 02924 break; 02925 case SCRTYPE_TRIPLESPOT2: 02926 Str.Load(_R(IDS_SCRTYPE_TRIPLESPOT2)); 02927 break; 02928 case SCRTYPE_ELLIPTICAL: 02929 Str.Load(_R(IDS_SCRTYPE_ELLIPTICAL)); 02930 break; 02931 case SCRTYPE_LINE: 02932 Str.Load(_R(IDS_SCRTYPE_LINE)); 02933 break; 02934 case SCRTYPE_CROSSHATCH: 02935 Str.Load(_R(IDS_SCRTYPE_CROSSHATCH)); 02936 break; 02937 case SCRTYPE_MEZZOTINT: 02938 Str.Load(_R(IDS_SCRTYPE_MEZZOTINT)); 02939 break; 02940 case SCRTYPE_SQUARE: 02941 Str.Load(_R(IDS_SCRTYPE_SQUARE)); 02942 break; 02943 case SCRTYPE_DITHER: 02944 Str.Load(_R(IDS_SCRTYPE_DITHER)); 02945 break; 02946 case SCRTYPE_SPOT1: 02947 Str.Load(_R(IDS_SCRTYPE_SPOT1)); 02948 break; 02949 default: 02950 known=FALSE; 02951 Str.Load(_R(IDS_SCRTYPE_SPOT1)); 02952 break; 02953 } 02954 02955 (*pString) = Str; 02956 02957 return known; 02958 } 02959 02960 02961 /****************************************************************************************** 02962 02963 void TypesetInfo::SetSeparations(BOOL sep) 02964 02965 Author : Mike 02966 Created : 11/6/95 02967 Inputs : sep = a boolean which enables or disables separation output 02968 Purpose : To turn off and on printing of separated output. 02969 02970 if enabled, we colour-separate all output 02971 02972 if disabled, we print normal composite output 02973 02974 ******************************************************************************************/ 02975 02976 void TypesetInfo::SetSeparations(BOOL sep) 02977 { 02978 MakeSeparations = sep; 02979 } 02980 02981 02982 02983 /****************************************************************************************** 02984 02985 void TypesetInfo::SetScreening(BOOL state, BOOL SetAllPlates = TRUE) 02986 02987 Author : Mike 02988 Created : 11/6/95 02989 Inputs : sep = a boolean which enables or disables the output of setscreen commands 02990 SetAllPlates = FALSE to simply record the new state in this info class (not 02991 recommended) 02992 TRUE to set the state in all the plates held in this class 02993 02994 Purpose : To turn off and on printing of screened output. 02995 02996 If screening is enabled, the colour plate screen ang, freq, function 02997 will be output to the printer 02998 02999 If disabled, no screening info willl be sent, and thus we use the 03000 printer default settings. 03001 03002 ******************************************************************************************/ 03003 03004 void TypesetInfo::SetScreening(BOOL state, BOOL SetAllPlates) 03005 { 03006 UseScreening = state; 03007 if (SetAllPlates) 03008 { 03009 ColourPlate *pPlate = GetFirstPlate(); 03010 while (pPlate != NULL) 03011 { 03012 pPlate->SetActiveScreening(state); 03013 pPlate = GetNextPlate(pPlate); 03014 } 03015 } 03016 } 03017 03018 03019 03020 /****************************************************************************************** 03021 03022 void TypesetInfo::SetPrintResolution(INT32 res, BOOL SetAllPlates = TRUE); 03023 03024 Author : Mike 03025 Created : 11/6/95 03026 Inputs : res = a dpi resolution 03027 SetAllPlates = FALSE to simply record the new printer resolution, 03028 TRUE to reset all contained colour plates to recommended 03029 default values for the new resolution. This will set 03030 angle, freq, and function for all plates. 03031 03032 Purpose : Use this function to set the prefered postscript device resolution. The 03033 resolution determines the set of preferred screen frequencies. 03034 03035 ******************************************************************************************/ 03036 03037 void TypesetInfo::SetPrintResolution(INT32 res, BOOL SetAllPlates) 03038 { 03039 PrintResolution = res; 03040 03041 if (SetAllPlates) 03042 ResetAllPlatesToDefaultScreens(); 03043 } 03044 03045 03046 03047 /****************************************************************************************** 03048 03049 void TypesetInfo::SetDefaultScreenFrequency(double freq, BOOL SetAllPlates = TRUE) 03050 03051 Author : Mike 03052 Created : 11/6/95 03053 Inputs : freq = a double representing the screen frequency in lpi (possibly fractional) 03054 SetAllPlates = FALSE to simply record the new printer resolution, 03055 TRUE to reset all contained colour plates to this new 03056 screening frequency. 03057 03058 Purpose : Use this function to set the preferred screening frequency used for plates 03059 03060 ******************************************************************************************/ 03061 03062 void TypesetInfo::SetDefaultScreenFrequency(double freq, BOOL SetAllPlates) 03063 { 03064 if (freq < 2.0 || freq > 10000.0) 03065 { 03066 ERROR3("Silly screen frequency"); 03067 return; 03068 } 03069 03070 ScreenFrequency = freq; 03071 03072 if (SetAllPlates) 03073 ResetAllPlatesToDefaultScreens(); 03074 } 03075 03076 03077 03078 /****************************************************************************************** 03079 03080 > void TypesetInfo::SetScreenFunction(ScreenType func, BOOL SetAllPlates = TRUE); 03081 03082 Author : Mike 03083 Created : 11/6/95 03084 Inputs : func = the screening function to set 03085 setall = TRUE, then set this screen type in all the plates in the plate list 03086 FALSE - only remember this as the default (not recommended!) 03087 03088 Purpose : Use this function to set the preferred screening function used for plates 03089 03090 ******************************************************************************************/ 03091 03092 void TypesetInfo::SetScreenFunction(ScreenType func, BOOL SetAllPlates) 03093 { 03094 DefaultScreenType = func; 03095 03096 if (SetAllPlates) 03097 { 03098 ColourPlate *pPlate = GetFirstPlate(); 03099 while (pPlate != NULL) 03100 { 03101 pPlate->SetScreenFunction(func); 03102 pPlate = GetNextPlate(pPlate); 03103 } 03104 } 03105 } 03106 03107 03108 03109 /****************************************************************************************** 03110 03111 > void TypesetInfo::ResetAllPlatesToDefaultScreens(void) 03112 03113 Author : Jason 03114 Created : 19/8/96 03115 03116 Purpose : Resets all attached ColourPlates to the recommended defaults for: 03117 Screen Angle 03118 Screen Frequency 03119 Screen Function (dot shape) 03120 03121 SeeAlso: SetPrintResolution; SetDefaultScreenFrequency; SetScreenFunction 03122 03123 ******************************************************************************************/ 03124 03125 void TypesetInfo::ResetAllPlatesToDefaultScreens(void) 03126 { 03127 INT32 Res = GetPrintResolution(); 03128 INT32 Freq = (INT32) floor(GetDefaultScreenFrequency()); 03129 03130 ColourPlate *pPlate = GetFirstPlate(); 03131 while (pPlate != NULL) 03132 { 03133 pPlate->ResetScreenToDefaults(Res, Freq); 03134 pPlate->SetScreenFunction(GetScreenFunction()); 03135 03136 pPlate = GetNextPlate(pPlate); 03137 } 03138 } 03139 03140 03141 03142 /****************************************************************************************** 03143 03144 > void TypesetInfo::EnsureAllPlatesHaveGlobalSettigns(void) 03145 03146 Author : Jason 03147 Created : 18/9/96 03148 03149 Purpose : For convenience and efficiency while rendering print jobs, ColourPlates 03150 have their own copies of certain "global" flags (such as whether 03151 screening is enabled). 03152 03153 As a consequence of this slightly untidy situation, it is possible for 03154 the colour plates to get out of step with the overall option stored 03155 in the TypesetInfo. To get around this, this function simply copies the 03156 overall option from the TypesetInfo into all its colour plates. 03157 03158 It should be called prior to printing etc to ensure that these 'global' 03159 settings are consistent across all plates and the parent TypesettingInfo 03160 03161 Notes: Currently copies the following states: 03162 * Screen function 03163 * Screening enabled flag 03164 03165 ******************************************************************************************/ 03166 03167 void TypesetInfo::EnsureAllPlatesHaveGlobalSettings(void) 03168 { 03169 ColourPlate *pPlate = GetFirstPlate(); 03170 while (pPlate != NULL) 03171 { 03172 pPlate->SetScreenFunction(GetScreenFunction()); 03173 pPlate->SetActiveScreening(AreScreening()); 03174 03175 pPlate = GetNextPlate(pPlate); 03176 } 03177 } 03178 03179 03180 03181 /****************************************************************************************** 03182 03183 > void TypesetInfo::SetPhotoNegative(BOOL state) 03184 03185 Author : Mike 03186 Created : 11/6/95 03187 Inputs : state = the state of the photonegative flag 03188 Purpose : Use this function to set the photonegative local flag. 03189 03190 ******************************************************************************************/ 03191 03192 void TypesetInfo::SetPhotoNegative(BOOL state) 03193 { 03194 PhotoNegative = state; 03195 } 03196 03197 03198 /****************************************************************************************** 03199 03200 > void TypesetInfo::SetOverprintBlack(BOOL Always) 03201 03202 Author : Jason 03203 Created : 7/8/96 03204 03205 Inputs : Always - FALSE to disbale, or TRUE to enable "Always overprint black" 03206 03207 Purpose : Sets whether "black" will be always be overprinted automatically. 03208 03209 This works as follows: 03210 Any colour which is defined as CMYK and which has more than 95% Key 03211 component is considered "black". When AlwaysOverprintBlack is enabled, 03212 such "black" colours will be overprinted automatically. 03213 03214 This option does not affect non-CMYK colours 03215 03216 Notes: The TypesetInfo constructor defaults to the FALSE (disabled) state 03217 03218 SeeAlso: RenderRegion::PrepareStrokeColour; RenderRegion::PrepareFillGeometry 03219 03220 ******************************************************************************************/ 03221 03222 void TypesetInfo::SetOverprintBlack(BOOL Always) 03223 { 03224 OverprintBlack = Always; 03225 } 03226 03227 03228 03229 /****************************************************************************************** 03230 03231 > BOOL TypesetInfo::CheckForExistingPlate(ColourPlateType Type, 03232 IndexedColour *SpotColour = NULL) 03233 03234 Author : Jason 03235 Created : 25/6/96 03236 Inputs : Type - The type of plate you are checking for 03237 SpotColour - If Type is COLOURPLATE_SPOT, then SpotColour should point 03238 to the IndexedColour defining the spot plate. It is ignored for all other 03239 types. 03240 03241 Returns : TRUE if a matching plate is already in the list 03242 FALSE if you'll need to create and add a new plate of that type 03243 03244 Purpose : Helper function for CreatePlateList. Determines if a plate of the given 03245 type is already available in the ColourPlate list. If Type is 03246 COLOURTYPE_SPOT, then SpotColour must also be specified. 03247 03248 Notes: This doesn't find an exact match for the ColourPlate, but simply another 03249 plate of the same type (e.g. Another CYAN plate, or another SPOT plate 03250 which is based on the same spot colour) - all other options (monochrome, 03251 screen settings etc) are ignored in the comparison. 03252 03253 ******************************************************************************************/ 03254 03255 BOOL TypesetInfo::CheckForExistingPlate(ColourPlateType Type, IndexedColour *SpotColour) 03256 { 03257 ERROR3IF(Type == COLOURPLATE_SPOT && SpotColour == NULL, "Illegal NULL param"); 03258 03259 ColourPlate *Ptr = GetFirstPlate(); 03260 03261 while (Ptr != NULL) 03262 { 03263 if (Ptr->GetType() == Type) 03264 { 03265 // Just for safety we will make sure that the plate uses the same setting 03266 // for screen function as we do. (The plate holds a copy of this info for 03267 // convenience, and we don't really want plates using different screens) 03268 Ptr->SetScreenFunction(GetScreenFunction()); 03269 03270 // The basic types match, but if it's a spot plate, we have to check if 03271 // it is the same actual spot plate before we have an exact match 03272 if (Type == COLOURPLATE_SPOT) 03273 { 03274 if (Ptr->GetSpotColour() == SpotColour) 03275 return(TRUE); 03276 //else 03277 // Not an exact match, so drop through to continue searching 03278 } 03279 else 03280 return(TRUE); // The types match, so return TRUE 03281 } 03282 03283 Ptr = GetNextPlate(Ptr); 03284 } 03285 03286 // We didn't find it, so return FALSE 03287 return(FALSE); 03288 } 03289 03290 03291 03292 /****************************************************************************************** 03293 03294 > BOOL TypesetInfo::CreatePlateList() 03295 03296 Author : Jason (shell function by Mike) 03297 Created : 25/6/96 (11/6/95 - 95? Are you sure, Mike? ;-) 03298 Inputs : - 03299 Returns : TRUE if the plate list has been constructed correctly 03300 FALSE if there's nothing in the plate list. 03301 03302 Purpose : This function initialises or re-initialises the document plate list. 03303 This list contains a set of ColourPlates which will be used to control 03304 the printing of the document. Each plate will produce a distinct pass 03305 in the print loop. 03306 03307 If the ColourPlate list has already been created, this function will 03308 update it by the following means: 03309 * Ensure that the process (C,M,Y,K) plates are in the list 03310 * Remove any Spot colours from the list which have since been deleted or 03311 edited to no longer be spot colours 03312 * Add any new spot colours to the plate list 03313 03314 Any existing plate settings for plates that are still valid will thus 03315 be retained. 03316 03317 ******************************************************************************************/ 03318 03319 BOOL TypesetInfo::CreatePlateList() 03320 { 03321 ColourPlate *pPlate; 03322 03323 INT32 Res = GetPrintResolution(); 03324 INT32 Freq = (INT32) floor(GetDefaultScreenFrequency()); 03325 03326 // --- First, make sure we've got a set of process (CMYK) plates... 03327 // Create a cyan plate to print. 03328 if (!CheckForExistingPlate(COLOURPLATE_CYAN)) 03329 { 03330 pPlate = new ColourPlate(COLOURPLATE_CYAN, TRUE, FALSE); 03331 if (pPlate) 03332 { 03333 pPlate->ResetScreenToDefaults(Res, Freq); 03334 pPlate->SetScreenFunction(GetScreenFunction()); 03335 03336 AddPlate(pPlate); 03337 } 03338 } 03339 03340 // Create a magenta plate to print. 03341 if (!CheckForExistingPlate(COLOURPLATE_MAGENTA)) 03342 { 03343 pPlate = new ColourPlate(COLOURPLATE_MAGENTA, TRUE, FALSE); 03344 if (pPlate) 03345 { 03346 pPlate->ResetScreenToDefaults(Res, Freq); 03347 pPlate->SetScreenFunction(GetScreenFunction()); 03348 03349 AddPlate(pPlate); 03350 } 03351 } 03352 03353 // Create a yellow plate to print. 03354 if (!CheckForExistingPlate(COLOURPLATE_YELLOW)) 03355 { 03356 pPlate = new ColourPlate(COLOURPLATE_YELLOW, TRUE, FALSE); 03357 if (pPlate) 03358 { 03359 pPlate->ResetScreenToDefaults(Res, Freq); 03360 pPlate->SetScreenFunction(GetScreenFunction()); 03361 03362 AddPlate(pPlate); 03363 } 03364 } 03365 03366 // Create a key plate to print. 03367 if (!CheckForExistingPlate(COLOURPLATE_KEY)) 03368 { 03369 pPlate = new ColourPlate(COLOURPLATE_KEY, TRUE, FALSE); 03370 if (pPlate) 03371 { 03372 pPlate->ResetScreenToDefaults(Res, Freq); 03373 pPlate->SetScreenFunction(GetScreenFunction()); 03374 03375 AddPlate(pPlate); 03376 } 03377 } 03378 03379 03380 // --- Second, remove any "dead" plates (spot colours which are now deleted or 03381 // have been edited so they are no longer spot colours) 03382 pPlate = (ColourPlate *) PrintingPlates.GetHead(); 03383 ColourPlate *pNext; 03384 while (pPlate != NULL) 03385 { 03386 pNext = (ColourPlate *) PrintingPlates.GetNext(pPlate); 03387 03388 if (pPlate->GetType() == COLOURPLATE_SPOT) 03389 { 03390 IndexedColour *pSpot = pPlate->GetSpotColour(); 03391 if (pSpot != NULL) 03392 { 03393 // If it's not a spot colour, or is deleted, then it no longer generates a plate 03394 if (pSpot->GetType() != COLOURTYPE_SPOT || pSpot->IsDeleted()) 03395 { 03396 PrintingPlates.RemoveItem(pPlate); 03397 delete pPlate; 03398 } 03399 } 03400 } 03401 pPlate = pNext; 03402 } 03403 03404 03405 // --- Finally, add plates for any spot colour which is not already accounted for 03406 // in the existing plate list. We use the colours from the Selected document 03407 ColourList *ColList = ColourManager::GetColourList(); 03408 ERROR3IF(ColList == NULL, "Can't find selected ColourList"); 03409 03410 if (ColList != NULL) 03411 { 03412 IndexedColour *IxCol = (IndexedColour *) ColList->GetUndeletedHead(); 03413 while (IxCol != NULL) 03414 { 03415 if (IxCol->GetType() == COLOURTYPE_SPOT) 03416 { 03417 // We've found a spot colour. Is it already represented by a ColourPlate? 03418 if (!CheckForExistingPlate(COLOURPLATE_SPOT, IxCol)) 03419 { 03420 // No, it's not, so we'd better create a new plate for it 03421 pPlate = new ColourPlate(IxCol, TRUE, FALSE); 03422 if (pPlate) 03423 { 03424 pPlate->ResetScreenToDefaults(Res, Freq); 03425 pPlate->SetScreenFunction(GetScreenFunction()); 03426 03427 AddPlate(pPlate); 03428 03429 // If this colour is not used in the document, turn off printing of the plate 03430 // by default. (This isn't brilliant - it'll leave it on if the colour is used 03431 // in the UNDO, but it's better than leaving it on all the time) 03432 // NOTE: We pass in TRUE so that it will ignore one use of the colour (the 03433 // reference from the ColourPlate itself!) 03434 if (!IxCol->IsInUse(TRUE)) 03435 pPlate->SetDisabled(TRUE); 03436 } 03437 } 03438 } 03439 03440 IxCol = (IndexedColour *) ColList->GetUndeletedNext(IxCol); 03441 } 03442 } 03443 03444 // And now, just make sure everything is tidy 03445 EnsureAllPlatesHaveGlobalSettings(); 03446 03447 return TRUE; 03448 } 03449 03450 03451 03452 /****************************************************************************************** 03453 03454 > void TypesetInfo::UpdatePlateList() 03455 03456 Author : Mike 03457 Created : 31/08/96 03458 Inputs : - 03459 Returns : - 03460 Purpose : Makes sure all the plates in the plate list have all values up-to-date. 03461 This is called on StartPrinting(). The reason it is here is that on 03462 start up, the previous settings will be loaded in and set in TypsetInfo. 03463 However, the user could print immediately without bringing up any extra 03464 print option tabs. The list of plates is created needs to be updated with 03465 the loaded settings. 03466 03467 ******************************************************************************************/ 03468 03469 void TypesetInfo::UpdatePlateList() 03470 { 03471 // Make sure all plate screening values are up-to-date 03472 SetScreening(UseScreening,TRUE); 03473 // Make sure screen plate / lpi / freq / angles are all correct 03474 ResetAllPlatesToDefaultScreens(); 03475 } 03476 03477 03478 /****************************************************************************************** 03479 03480 > ColourPlate *TypesetInfo::CreateColourPlate() 03481 03482 Author : Jason 03483 Created : 16/8/96 03484 Inputs : - 03485 Returns : NULL (failed) or a new colour plate 03486 03487 Purpose : Creates a new colour plate 03488 The plate defaults to the same as for the ColourPlate() default constructor 03489 (i.e. COLOURPLATE_NONE), but things like the screen function will be set 03490 up by copying them from this TypesetInfo object. 03491 03492 This function is intended only for use by the native file import code, 03493 which creates colour plates if any were saved in the file. However, each 03494 plate takes many settings from its parent TypesetInfo (they're only stored 03495 in the plate for easy access/efficiency when rendering) 03496 03497 Notes: See Also CheckForExistingPlate() which also sets the plate screen functions to 03498 make sure they tow the party line... 03499 03500 ******************************************************************************************/ 03501 03502 ColourPlate *TypesetInfo::CreateColourPlate() 03503 { 03504 ColourPlate *pNewPlate = new ColourPlate(COLOURPLATE_NONE, TRUE, FALSE); 03505 03506 // The only special info we currently need to set is the screen function... 03507 if (pNewPlate != NULL) 03508 pNewPlate->SetScreenFunction(GetScreenFunction()); 03509 03510 return(pNewPlate); 03511 } 03512 03513 03514 03515 /****************************************************************************************** 03516 03517 > void TypesetInfo::DestroyPlateList() 03518 03519 Author : Mike 03520 Created : 11/6/95 03521 Inputs : - 03522 Returns : - 03523 Purpose : This function simply empties the entire plate list of its contents, deleting 03524 each record as it goes. It is a seriously non-constant function. 03525 03526 ******************************************************************************************/ 03527 03528 void TypesetInfo::DestroyPlateList() 03529 { 03530 ColourPlate *pPlate; 03531 while ((pPlate=(ColourPlate*)PrintingPlates.RemoveTail())) // Assignment 03532 delete pPlate; 03533 03534 // We have no plates, so it's best to vape our current pointers 03535 CurrentPlate = NULL; 03536 CurrentPrintPlate = NULL; 03537 } 03538 03539 /****************************************************************************************** 03540 03541 > void TypesetInfo::AddPlate(ColourPlate* pPlate) 03542 03543 Author : Mike 03544 Created : 11/6/95 03545 Inputs : pPlate = a pointer to a colour plate 03546 Returns : - 03547 Purpose : Use this function to add a colour plate to the colour plate list. 03548 Note, the calling function no longer has ownership of this object. The object 03549 will be deleted automatically from the list whenever the plate list class is 03550 destroyed. 03551 03552 ******************************************************************************************/ 03553 03554 void TypesetInfo::AddPlate(ColourPlate* pPlate) 03555 { 03556 ERROR3IF(pPlate==NULL, "AddPlate given a NULL plate pointer!"); 03557 PrintingPlates.AddTail(pPlate); 03558 } 03559 03560 /****************************************************************************************** 03561 03562 > void TypesetInfo::SetCurrentPlate(ColourPlate* pPlate) 03563 03564 Author : Mike 03565 Created : 11/6/95 03566 Inputs : pPlate = a pointer to a colour plate 03567 Returns : - 03568 Purpose : Use this function to set the current colour plate. This current plate 03569 object is usually shown as the highlighted plate in the printing dialogue 03570 plate display list. 03571 03572 ******************************************************************************************/ 03573 03574 void TypesetInfo::SetCurrentPlate(ColourPlate* pPlate) 03575 { 03576 ERROR3IF(pPlate==NULL, "SetCurrentPlate given a NULL plate pointer!"); 03577 CurrentPlate = pPlate; 03578 } 03579 03580 /****************************************************************************************** 03581 03582 > ColourPlate* TypesetInfo::GetCurrentPlate() const 03583 03584 Author : Mike 03585 Created : 11/6/95 03586 Inputs : - 03587 Returns : a pointer to the current colour plate 03588 Purpose : Use this function to retrieve a pointer to the current plate. 03589 The current plate variable simply keeps track of the selected plate in the 03590 printing UI. This plate is the one which will receive all edits. 03591 03592 ******************************************************************************************/ 03593 03594 ColourPlate* TypesetInfo::GetCurrentPlate() const 03595 { 03596 return CurrentPlate; 03597 } 03598 03599 03600 /****************************************************************************************** 03601 03602 > DWORD TypesetInfo::GetNumPlates() const 03603 03604 Author : Mike 03605 Created : 11/6/95 03606 Inputs : - 03607 Returns : a dword, the number of plates in the list 03608 Purpose : Returns the number of plates in the print class plate list 03609 03610 ******************************************************************************************/ 03611 03612 DWORD TypesetInfo::GetNumPlates() const 03613 { 03614 return PrintingPlates.GetCount(); 03615 } 03616 03617 03618 03619 03620 /****************************************************************************************** 03621 03622 > void TypesetInfo::InitPlatesForPrinting() 03623 03624 Author : Mike 03625 Created : 11/6/95 03626 Inputs : - 03627 Returns : - 03628 Purpose : Set up the plate printing service. This should be called before any attempt 03629 to access the functions GetNextPrintPlate(), NumPrintPlatesRemaining etc 03630 03631 ******************************************************************************************/ 03632 03633 void TypesetInfo::InitPlatesForPrinting() 03634 { 03635 // We don't need to do anything if we're not separating, but as we 03636 // do nothing but set a plate, we don't need extra check code here 03637 // Set our internal current plate 03638 CurrPrintPlateNum=1; 03639 NumPrintPlates=1; 03640 CurrentPrintPlate=NULL; 03641 PrintPlatesToGo=1; 03642 03643 if (AreSeparating()) 03644 { 03645 NumPrintPlates = GetNumPrintPlates(); 03646 PrintPlatesToGo = NumPrintPlates; 03647 } 03648 } 03649 03650 03651 03652 /****************************************************************************************** 03653 03654 > ColourPlate* TypesetInfo::GetFirstPrintPlate() 03655 03656 Author : Mike 03657 Created : 11/6/95 03658 Inputs : - 03659 Returns : A pointer to the first print plate (NULL if no more) 03660 Purpose : Return the first plate through which the document will be printed. 03661 The class variables CurrentPrintPlate and CurrPrintPlateNum will be 03662 set. 03663 03664 ******************************************************************************************/ 03665 03666 ColourPlate* TypesetInfo::GetFirstPrintPlate() 03667 { 03668 // Retrieve the first plate from the list 03669 ColourPlate *pPlate = GetFirstPlate(); 03670 return GetPrintPlate(0,pPlate); 03671 } 03672 03673 /****************************************************************************************** 03674 03675 > ColourPlate* TypesetInfo::GetNextPrintPlate() 03676 03677 Author : Mike 03678 Created : 11/6/95 03679 Inputs : - 03680 Returns : A pointer to the next print plate (NULL if no more) 03681 Purpose : Return the next plate through which the document will be printed. 03682 The class variables CurrentPrintPlate and CurrPrintPlateNum will be 03683 used to determin the next plate 03684 03685 ******************************************************************************************/ 03686 03687 ColourPlate* TypesetInfo::GetNextPrintPlate() 03688 { 03689 ColourPlate *pPlate; 03690 if (CurrentPrintPlate==NULL) 03691 { 03692 // Retrieve the first plate from the list 03693 pPlate = GetFirstPlate(); 03694 return GetPrintPlate(0,pPlate); 03695 } 03696 // otherwise retrieve the next plate 03697 pPlate = GetNextPlate(CurrentPrintPlate); 03698 return GetPrintPlate(CurrPrintPlateNum,pPlate); 03699 } 03700 03701 03702 /****************************************************************************************** 03703 03704 ColourPlate* TypesetInfo::GetPrintPlate(DWORD num, ColourPlate* pPlate) 03705 03706 Author : Mike 03707 Created : 11/6/95 03708 Inputs : num = the number of the plate 03709 pPlate = a pointer to the plate 03710 Returns : A pointer to a print plate (NULL if none) 03711 Purpose : This function is an internal helper function to GetFirstPrintPlate() and 03712 GetNextPrintPlate() 03713 03714 ******************************************************************************************/ 03715 03716 ColourPlate* TypesetInfo::GetPrintPlate(DWORD pnum, ColourPlate* pPlate) 03717 { 03718 while (pPlate!=NULL) 03719 { 03720 pnum++; 03721 // if this plate is not disabled then return it 03722 if (!pPlate->IsDisabled()) 03723 { 03724 CurrPrintPlateNum=pnum; 03725 PrintPlatesToGo--; 03726 return (CurrentPrintPlate=pPlate); 03727 } 03728 pPlate=GetNextPlate(pPlate); 03729 } 03730 return NULL; 03731 } 03732 03733 03734 /****************************************************************************************** 03735 03736 > DWORD TypesetInfo::GetNumPrintPlates() const 03737 03738 Author : Mike 03739 Created : 11/6/95 03740 Inputs : - 03741 Returns : A DWORD, the number of plates this document can theoretically be separated 03742 to. This will usually be 4 (C,M,Y and K) plus any spot colour plates 03743 Purpose : Find out how many print plates are stored in the plate list. 03744 03745 ******************************************************************************************/ 03746 03747 DWORD TypesetInfo::GetNumPrintPlates() const 03748 { 03749 ColourPlate* pPlate; 03750 DWORD nPlates=0; 03751 03752 pPlate = GetFirstPlate(); 03753 while (pPlate!=NULL) 03754 { 03755 if (!pPlate->IsDisabled()) 03756 nPlates++; 03757 pPlate=GetNextPlate(pPlate); 03758 } 03759 return nPlates; 03760 } 03761 03762 03763 /****************************************************************************************** 03764 03765 > ColourPlate* TypesetInfo::GetCurrentPlate() const 03766 03767 Author : Jason 03768 Created : 5/8/96 03769 Inputs : - 03770 Returns : a pointer to the currently PRINTING colour plate 03771 Purpose : Use this function to retrieve a pointer to the currently printing plate. 03772 03773 ******************************************************************************************/ 03774 03775 ColourPlate* TypesetInfo::GetCurrentPrintPlate() const 03776 { 03777 return CurrentPrintPlate; 03778 } 03779 03780 03781 /****************************************************************************************** 03782 03783 > void TypesetInfo::NumPrintPlatesRemaining() 03784 03785 Author : Mike 03786 Created : 11/6/95 03787 Inputs : - 03788 Returns : The number of plate which remain to be printed 03789 Purpose : Calculate and return the number of plates remaining for this piece of paper 03790 03791 ******************************************************************************************/ 03792 03793 INT32 TypesetInfo::NumPrintPlatesRemaining() const 03794 { 03795 // Calculate the number of plates remaining print 03796 return ( PrintPlatesToGo ); 03797 } 03798 03799 03800 /****************************************************************************************** 03801 03802 > void TypesetInfo::SetNextCompositePlate() 03803 03804 Author : Mike 03805 Created : 11/6/95 03806 Inputs : - 03807 Returns : - 03808 Purpose : Called from PrintControl::SetNextPlate(). This function simply allows 03809 composite printing to pass around the plate loop once without actually 03810 setting any plates. This function will set the internal typeset plate 03811 variables so that MorePlates() will return FALSE the next time it is 03812 called. 03813 03814 ******************************************************************************************/ 03815 03816 void TypesetInfo::SetNextCompositePlate() 03817 { 03818 // Do absolutely nothing if we are in separation mode 03819 if (AreSeparating()) 03820 return; 03821 03822 // Set out internal variables so a call to MorePlates() 03823 // will terminate the print loop 03824 CurrentPrintPlate=NULL; 03825 PrintPlatesToGo=0; 03826 }