// $Id: printctl.cpp 1454 2006-07-17 11:52:51Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // // Implementation of the print control class /* */ #include "camtypes.h" //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "colcontx.h" #include "colourix.h" #include "colormgr.h" #include "colplate.h" #include "camelot.h" //#include "convert.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "justin2.h" //#include "markn.h" #include "osrndrgn.h" #include "prdlgctl.h" #include "princomp.h" #include "printctl.h" #include "prntview.h" //#include "resource.h" //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "simon.h" //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "tim.h" //#include "view.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "prnmks.h" //#include "isetres.h" CC_IMPLEMENT_MEMDUMP(PrintControl, CC_CLASS_MEMDUMP) CC_IMPLEMENT_MEMDUMP(PrintPatchInfo,CC_CLASS_MEMDUMP) CC_IMPLEMENT_MEMDUMP(TypesetInfo, CC_CLASS_MEMDUMP) // This is not compulsory, but you may as well put it in so that the correct version // of your file can be registered in the .exe DECLARE_SOURCE("$Revision: 1454 $"); #define Swap(a,b) { (a)^=(b), (b)^=(a), (a)^=(b); } // This is the max DPI at which bitmaps will be printed when using automatic DPI calculations #define MAXAUTOBITMAPDPI 200 // These two values determine the range of values that the bitmap DPI will lie within #define MINBITMAPDPI 10 #define MAXBITMAPDPI 600 // Constants used for initialisation #define A4_WIDTH (INT32(MM_MP_VAL*210)) // 210 mm - A4 width #define A4_HEIGHT (INT32(MM_MP_VAL*297)) // 297 mm - A4 height //---------------------------------------------------------------- static INT32 MinPrintScale = 5; static INT32 MaxPrintScale = 999; PrintMethodType PrintControl::AppPrintMethod = PRINTMETHOD_NORMAL; // ini file entry declared in princomp.cpp // if ( Camelot.DeclareSection(TEXT("Preferences"), 3) ) // { // section declared ok so now define the preference option // Camelot.DeclarePref(TEXT("Preferences"), TEXT("MinPrintScale"), &MinPrintScale, 1); // Camelot.DeclarePref(TEXT("Preferences"), TEXT("MaxPrintScale"), &MaxPrintScale, 1); /****************************************************************************************** > PrintControl::PrintControl() Author: Mark_Neves (Xara Group Ltd) Created: 27/3/95 Inputs: - Outputs: - Returns: - Purpose: Default constructor Errors: - SeeAlso: - ******************************************************************************************/ PrintControl::PrintControl() { PrintAreaSetUp = FALSE; // We haven't set the control up with a print area yet SetUpFailed = FALSE; // We haven't called SetUp yet, so we haven't failed yet pSpread = NULL; TotalPrintArea = DocRect(0,0,A4_WIDTH,A4_HEIGHT); PrintableArea = TotalPrintArea; PALeftMargin = 0; PATopMargin = 0; Origin = DocCoord(0,A4_HEIGHT); PageWidth = A4_WIDTH; PageHeight = A4_HEIGHT; PaperWidth = A4_WIDTH; PaperHeight = A4_HEIGHT; DPS = FALSE; Bleed = 0; CropArea = CROPAREA_SIZE+OUTSIDEBLEEDWIDTH; CropTopMargin = 0; CropLeftMargin = 0; // Print layout vars WholeSpread = FALSE; Scale = FIXED16(100); Orient = PRINTORIENTATION_UPRIGHT; FitType = PRINTFIT_BESTPAPER; TopMargin = 0; LeftMargin = 0; ScaledWidth = A4_WIDTH; ScaledHeight= A4_HEIGHT; Rows = 1; Columns = 1; Gutter = 0; // Print output vars Layers = PRINTLAYERS_VISIBLEFOREGROUND; // Job 10463: remove PS Level bits - default to Level 2 PSLangLevel = PSLEVEL_2; // PrintMethod = CurrentPrintMethod; BitmapResolutionMethod = BITMAPRES_AUTO; DotsPerInch = 150; FillQuality = PRINTFILLQUALITY_MEDIUM; TextOptions = PRINTTEXTOPTIONS_NORMAL; // General print vars Collated = FALSE; NumCopies = 1; PrintToFile = FALSE; ObjPrintRange = PRINTRANGEOBJ_ALL; DPSPrintRange = PRINTRANGEDPS_BOTH; // Misc UpdateDependants = TRUE; // Print layout var initialisation Printing = FALSE; }; /****************************************************************************************** > PrintControl::~PrintControl() Author: Mark_Neves (Xara Group Ltd) Created: 27/3/95 Inputs: - Outputs: - Returns: - Purpose: Default deconstructor Errors: - SeeAlso: PrintControl()::PrintControl() ******************************************************************************************/ PrintControl::~PrintControl() { // Does nowt as yet } /****************************************************************************************** > String_256 PrintControl::BuildPrintInfoStr() Author: Mark_Neves (Xara Group Ltd) Created: 7/4/95 Inputs: - Outputs: - Returns: Returns the print info string Purpose: This uses the print control's settings to build the string displayed in the print info field of a print dlg Errors: - SeeAlso: - ******************************************************************************************/ String_256 PrintControl::BuildPrintInfoStr() { String_256 Str; switch (FitType) { case PRINTFIT_BEST: Str = String_256(_R(IDS_PRINT_BESTFIT)); break; case PRINTFIT_CUSTOM: Str = String_256(_R(IDS_PRINT_CUSTOMFIT)); break; case PRINTFIT_MULTIPLE: Str = String_256(_R(IDS_PRINT_MULTIPLEFIT));break; case PRINTFIT_BESTPAPER:Str = String_256(_R(IDS_PRINT_BESTFITPAPER)); break; default: ERROR3_PF(("Unknown fit type (%d)",FitType)); break; } TCHAR* format = _T("%.2lf%%"); double fScale = Scale.MakeDouble(); INT32 n = INT32((fScale*100)+0.5); if (n % 100 == 0) format = _T("%.0lf%%"); else if (n % 10 == 0) format = _T("%.1lf%%"); TCHAR s[100]; camSprintf(s,format,fScale); Str += s; switch (Orient) { case PRINTORIENTATION_UPRIGHT: Str += String_256(_R(IDS_PRINT_UPRIGHT)); break; case PRINTORIENTATION_SIDEWAYS: Str += String_256(_R(IDS_PRINT_SIDEWAYS)); break; default: ERROR3_PF(("Unknown orientation (%d)",Orient)); break; } // If no print area set up, then assume we have no printer connected if (!PrintAreaSetUp) { Str += String_256(_R(IDS_PRINT_NOPRINTER)); return Str; } // Work out how many pages will get completely printed UINT32 NumPages = 1; UINT32 IDSPlural = _R(IDS_PRINT_PAGES); UINT32 IDSSingular = _R(IDS_PRINT_PAGE); switch (FitType) { case PRINTFIT_BEST: case PRINTFIT_BESTPAPER: NumPages = 1; break; case PRINTFIT_MULTIPLE: NumPages = 0; if (StartPrinting()) { GetNextPaper(); PrintPatchInfo PatchInfo; while (GetNextPatch(&PatchInfo)) { DocRect Rect = PatchInfo.GetClipRect(FALSE,FALSE); double ScaleFactor = PatchInfo.Scale.MakeDouble() / 100; INT32 w = Rect.Width(); INT32 h = Rect.Height(); if (PatchInfo.Rotate) { INT32 t = w; w = h; h = t; } Rect.lo.x = PatchInfo.XTrans; Rect.lo.y = PatchInfo.YTrans; Rect.hi.x = Rect.lo.x + (INT32((double(w) * ScaleFactor)+0.5)); Rect.hi.y = Rect.lo.y + (INT32((double(h) * ScaleFactor)+0.5)); if (PrintableArea.ContainsRect(Rect)) NumPages++; } EndPrinting(); } IDSPlural = _R(IDS_PRINT_TILES); IDSSingular = _R(IDS_PRINT_TILE); break; case PRINTFIT_CUSTOM: { DocRect Rect(0,PaperHeight-ScaledHeight,ScaledWidth,PaperHeight); INT32 CropAdj = GetCropAdjust(); INT32 TransX = LeftMargin + CropAdj; INT32 TransY = TopMargin + CropAdj; Rect.Translate(TransX,-TransY); if (PrintableArea.ContainsRect(Rect)) NumPages = 1; else NumPages = 0; } break; } if (NumPages >= 1) { camSprintf(s, TEXT("%ld") ,NumPages); Str += s; if (NumPages == 1) Str += String_256(IDSSingular); else Str += String_256(IDSPlural); } else Str += String_256(_R(IDS_PRINT_NOPAGESFIT)); return Str; } /****************************************************************************************** > String_256 PrintControl::BuildPaperSizeStr() Author: Mark_Neves (Xara Group Ltd) Created: 7/4/95 Inputs: - Outputs: - Returns: Returns the paper size string Purpose: This uses the printer settings to build the string displayed in the paper size field of a print options tab Errors: - SeeAlso: - ******************************************************************************************/ String_256 PrintControl::BuildPaperSizeStr() { String_256 Str = TEXT(""); String_256 TempStr = TEXT(""); // If no print area set up, then assume we have no printer connected if (!PrintAreaSetUp) return Str; DimScale* pDimScale = NULL; if (pSpread != NULL) pDimScale = DimScale::GetPtrDimScale(pSpread); if (pDimScale != NULL) { BOOL ActiveState = pDimScale->IsActive(); pDimScale->SetActiveState(FALSE); pDimScale->ConvertToUnits(PaperWidth,&TempStr); Str += TempStr; Str += String_32(_R(IDS_NUM_BY_NUM)); pDimScale->ConvertToUnits(PaperHeight,&TempStr); Str += TempStr; // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER INT32 PrScale; if (CCPrintDialog::GetScale(&PrScale)) { if (PrScale != 100) { Str += String_256(_R(IDS_PRINT_PRINTERSCALING)); TCHAR s[100]; String_32 jcf(_R(IDS_PERCENT_FORMAT)); camSprintf(s, jcf, (INT32) PrScale); Str += s; } } #endif //webster pDimScale->SetActiveState(ActiveState); } return Str; } /****************************************************************************************** > PrintControl& PrintControl::operator=(PrintControl& other) Author: Mark_Neves (Xara Group Ltd) Created: 27/3/95 Inputs: the object to copy Outputs: - Returns: ref to copy of other Purpose: The assignment operator for PrintControl Errors: - SeeAlso: - ******************************************************************************************/ PrintControl& PrintControl::operator=(PrintControl& other) { PrintAreaSetUp = other.PrintAreaSetUp; SetUpFailed = other.SetUpFailed; pSpread = other.pSpread; TotalPrintArea = other.TotalPrintArea; PrintableArea = other.PrintableArea; PALeftMargin = other.PALeftMargin; PATopMargin = other.PATopMargin; Origin = other.Origin; PaperWidth = other.PaperWidth; PaperHeight = other.PaperHeight; PageWidth = other.PageWidth; PageHeight = other.PageHeight; OrigPageWidth = other.OrigPageWidth; OrigPageHeight = other.OrigPageHeight; // Print layout vars WholeSpread = other.WholeSpread; DPS = other.DPS; Bleed = other.Bleed; CropArea = other.CropArea; CropTopMargin = other.CropTopMargin; CropLeftMargin = other.CropLeftMargin; Scale = other.Scale; Orient = other.Orient; FitType = other.FitType; TopMargin = other.TopMargin; LeftMargin = other.LeftMargin; ScaledWidth = other.ScaledWidth; ScaledHeight= other.ScaledHeight; Rows = other.Rows; Columns = other.Columns; Gutter = other.Gutter; // Print output vars Layers = other.Layers; PSLangLevel = other.PSLangLevel; // PrintMethod = other.PrintMethod; BitmapResolutionMethod = other.BitmapResolutionMethod; DotsPerInch = other.DotsPerInch; FillQuality = other.FillQuality; TextOptions = other.TextOptions; // General print vars Collated = other.Collated; NumCopies = other.NumCopies; PrintToFile = other.PrintToFile; ObjPrintRange = other.ObjPrintRange; DPSPrintRange = other.DPSPrintRange; // The TypesetInfo Typesetting = other.Typesetting; // Finally, make sure we have calculated all of the print settings like scaling properly if (pSpread != NULL) SetUp(pSpread); return *this; }; //------------------------------------------------ /****************************************************************************************** > BOOL PrintControl::SetUp(Spread* pThisSpread, BOOL RedrawPrintBorders = TRUE) Author: Mark_Neves (Xara Group Ltd) Created: 4/4/95 Inputs: pThisSpread = ptr to a spread to print RedrawPrintBorders - True if want a force redraw of associated docs (Defaults to TRUE) Outputs: PrintAreaSetUp has same BOOL value as the return result Returns: TRUE if able to set up print area OR already set up Purpose: This function sets up the print control to print the given spread. The entire spread area is used as the source area to print. It can determine from the spread whether it is a double page spread (DPS) or not. Once it gets the source area for printing from the spread, it calcs the fit for the spread using the current fit type. I.e. it works out the scale factor and scaled page width and height for each page printed, given the current settings. Errors: - SeeAlso: - ******************************************************************************************/ BOOL PrintControl::SetUp(Spread* pThisSpread, BOOL RedrawPrintBorders) { ERROR2IF(pThisSpread == NULL,FALSE,"pThisSpread is NULL"); pSpread = pThisSpread; // find out if it's a double page spread if (!pSpread->GetPageSize(NULL,NULL,NULL,&Bleed,&DPS,NULL)) return FALSE; // Get a union of all the pages that represents the total printable area of the spread pSpread->GetPagesRect(&TotalPrintArea); PrintAreaSetUp = (CalcPrintAreaVars(RedrawPrintBorders) && CalcFit()); SetUpFailed = !PrintAreaSetUp; return PrintAreaSetUp; } /****************************************************************************************** > BOOL PrintControl::CalcPrintAreaVars(BOOL RedrawPrintBorders = TRUE) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: RedrawPrintBorders - True if want a force redraw of associated docs (Defaults to TRUE) Outputs: - Returns: TRUE if able to recalc Purpose: This function calcs member vars dependant on the total print area. The print area can be set up using SetUp(). Dependants are: PageWidth PageHeight Origin PrintableArea It takes into account orientation, and whether its a double page spread (DPS). If it's a DPS, it also takes the WholeSpread setting into account NOTE: This func also finds out the width and height of the printer's paper using CCPrintDialog::GetPaperSize(), and calcs the paper's area too Errors: - SeeAlso: SetUp() ******************************************************************************************/ BOOL PrintControl::CalcPrintAreaVars(BOOL RedrawPrintBorders) { // Calc the print area origin Origin.x = TotalPrintArea.lo.x; Origin.y = TotalPrintArea.hi.y; //------------------------- // Find out the dimensions of the printer's paper (in MILLIPOINTS) wxSize PaperSize; // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER if (!CCPrintDialog::GetPaperSize(&PaperSize, RedrawPrintBorders)) return FALSE; #endif //webster PaperWidth = PaperSize.GetWidth(); PaperHeight = PaperSize.GetHeight(); // ------------------------ // Get the printable area on the paper (defined relative to a origin at the bottom left of paper) // and the top & left margins of the printable area // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER if (!CCPrintDialog::GetPrintableArea(&PrintableArea)) return FALSE; if (!CCPrintDialog::GetPrintMargins(&PALeftMargin,&PATopMargin)) return FALSE; #endif //webster //------------------------- // Calc the width and height of the print area PageWidth = TotalPrintArea.hi.x - TotalPrintArea.lo.x; PageHeight = TotalPrintArea.hi.y - TotalPrintArea.lo.y; // If double page spread AND printing single pages, half the width for each page printed if (DPS && !WholeSpread) (PageWidth) /= 2; // Save the orig values in case PageWidth & PageHeight need to be swapped due to sideways orientation OrigPageWidth = PageWidth; OrigPageHeight = PageHeight; // If printing sideways, the width and height of the printed page should be swapped if (Orient == PRINTORIENTATION_SIDEWAYS) Swap(PageWidth,PageHeight); return TRUE; } /****************************************************************************************** > void PrintControl::StartImport() Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: - Purpose: Tells the object that it's data is being imported. In this state, calling the Set functions just sets the aspect of the object, rather than recalculation dependant aspects of the object. e.g. calling SetScale() will recalc the width & height of the printed page unless you call StartImport() first You can call this func any time, not just for importing, if you need to alter mmembers independently. SeeAlso: EndImport() ******************************************************************************************/ void PrintControl::StartImport() { UpdateDependants = FALSE; } /****************************************************************************************** > void PrintControl::StartImport() Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: - Purpose: Tells the object that it's data is no longer being imported. SeeAlso: StartImport() ******************************************************************************************/ void PrintControl::EndImport() { UpdateDependants = TRUE; } //------------------------- /****************************************************************************************** > INT32 PrintControl::GetNumPrintablePages() Author: Mark_Neves (Xara Group Ltd) Created: 12/4/95 Inputs: - Returns: Number of printable pages (1 or 2) Purpose: This tells you how many individual pages are printable, given the current settings 1 is returned: If it's not a DPS If it's a DPS, but we're printing the whole spread as one page If it's a DPS, we're printing individual pages, but the print range is either Left or Right-only 2 is returned: It's a DPS AND individual pages AND printing both pages SeeAlso: - ******************************************************************************************/ INT32 PrintControl::GetNumPrintablePages() { if (DPS && !WholeSpread && (DPSPrintRange == PRINTRANGEDPS_BOTH)) return 2; else return 1; } //------------------------- /****************************************************************************************** > void PrintControl::SetScaleFactor(double ScaleFactor) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: ScaleFactor = the scale factor Purpose: Sets the scale percentage using the given scale factor This alters dependants automatically (unless importing) Dependants are: ScaledWidth ScaledHeight SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetScaleFactor(double ScaleFactor) { SetScale(FIXED16(100*ScaleFactor)); } /****************************************************************************************** > void PrintControl::SetScale(FIXED16 NewScale) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewScale = new scale factor Purpose: Sets the scale percentage, altering dependants automatically (unless importing) Dependants are: ScaledWidth ScaledHeight SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetScale(FIXED16 NewScale) { Scale = NewScale; FIXED16 Min = FIXED16(MinPrintScale); FIXED16 Max = FIXED16(MaxPrintScale); if (Scale < Min) Scale = Min; if (Scale > Max) Scale = Max; if (UpdateDependants) { double ScaleFactor = (Scale.MakeDouble())/100; ScaledWidth = INT32((double(PageWidth) *ScaleFactor)+0.5); ScaledHeight = INT32((double(PageHeight)*ScaleFactor)+0.5); } } /****************************************************************************************** > void PrintControl::SetPrintOrient(PrintOrient NewOrient) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewOrient = new orientation Purpose: Sets the print orientatio, altering dependants automatically (unless importing) Dependants are: ScaledWidth ScaledHeight PageWidth PageHeight Scale and possibly: Rows Columns SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetPrintOrient(PrintOrient NewOrient) { if (Orient != NewOrient) { Orient = NewOrient; if (UpdateDependants) { CalcPrintAreaVars(); // Update the page width and height (these get swapped) SetRows(Rows); // Use SetRows() to recalc max rows and scale factor SetColumns(Columns); // Use SetColumns() to recalc max columns and scale factor // This is a bodge fix. Sometimes the gutter value can become -ve. In this case, // reset the multiple fit vars if (Gutter < 0) { SetRows(1); // Use SetRows() to recalc max rows and scale factor SetColumns(1); // Use SetColumns() to recalc max columns and scale factor SetGutter(0); } } } } /****************************************************************************************** > void PrintControl::SetWidth(INT32 NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewVal = new width for the print area Purpose: Sets the page width, altering dependants automatically (unless importing) Dependants are: Scale ScaledHeight SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetWidth(INT32 NewVal) { if (UpdateDependants) { double ScaleFactor = double(NewVal)/double(PageWidth); SetScaleFactor(ScaleFactor); // Use SetScaleFactor() to recalc ScaledWidth and ScaledHeight } else ScaledWidth = NewVal; } /****************************************************************************************** > void PrintControl::SetHeight(INT32 NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewVal = new height for the print area Purpose: Sets the page height, altering dependants automatically (unless importing) Dependants are: Scale ScaledWidth SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetHeight(INT32 NewVal) { if (UpdateDependants) { double ScaleFactor = double(NewVal)/double(PageHeight); SetScaleFactor(ScaleFactor); // Use SetScaleFactor() to recalc ScaledWidth and ScaledHeight } else ScaledHeight = NewVal; } //------------------------- //------------------------- //------------------------- /****************************************************************************************** > double PrintControl::CalcPatchWidth(INT32 Wd,INT32 NumColumns, INT32 GutterVal) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: Wd = Width of paper NumColumns = number of columns down the paper Gutter = gutter distance between each page Returns: The width of each patch for multiple fit printing Purpose: The patch width = (width of the paper / num columns) - gutter SeeAlso: - ******************************************************************************************/ double PrintControl::CalcPatchWidth(INT32 Wd,INT32 NumColumns,INT32 GutterVal) { return ((double(Wd) / double(NumColumns)) - double(GutterVal)); } /****************************************************************************************** > double PrintControl::CalcPatchHeight(INT32 Ht,INT32 NumRows,INT32 GutterVal) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: Ht = Height of paper NumRows = number of rows across the paper Gutter = gutter distance between each page Returns: The Height of each patch for multiple fit printing Purpose: The patch Height = (Height of the paper / num rows) - gutter SeeAlso: - ******************************************************************************************/ double PrintControl::CalcPatchHeight(INT32 Ht,INT32 NumRows,INT32 GutterVal) { return ((double(Ht) / double(NumRows)) - double(GutterVal)); } /****************************************************************************************** > INT32 PrintControl::CalcMaxRows(INT32 GutterVal) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: GutterVal = the gutter value to use Returns: Max num rows for the current paper width and gutter setting Purpose: Dynamically calcs the max num rows possible, given the current paper width and gutter setting. This is based on the min scale factor allowed SeeAlso: - ******************************************************************************************/ INT32 PrintControl::CalcMaxRows(INT32 GutterVal) { INT32 MaxRows = 0; double MinScaleFactor = double(MinPrintScale)/100; double PatchHeight,ScaleFactor; do { MaxRows += 1; PatchHeight = CalcPatchHeight(PaperHeight,MaxRows,GutterVal); ScaleFactor = PatchHeight / PageHeight; } while (ScaleFactor >= MinScaleFactor); if (MaxRows > 1) MaxRows -= 1; return MaxRows; } /****************************************************************************************** > INT32 PrintControl::CalcMaxColumns(INT32 GutterVal) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: GutterVal = the gutter value to use Returns: Max num columns for the current paper height and gutter setting Purpose: Dynamically calcs the max num columns possible, given the current paper height and gutter setting. This is based on the min scale factor allowed SeeAlso: - ******************************************************************************************/ INT32 PrintControl::CalcMaxColumns(INT32 GutterVal) { INT32 MaxColumns = 0; double MinScaleFactor = double(MinPrintScale)/100; double PatchWidth,ScaleFactor; do { MaxColumns += 1; PatchWidth = CalcPatchWidth(PaperWidth,MaxColumns,GutterVal); ScaleFactor = PatchWidth / PageWidth; } while (ScaleFactor >= MinScaleFactor); if (MaxColumns > 1) MaxColumns -= 1; return MaxColumns; } /****************************************************************************************** > INT32 PrintControl::CalcMaxGutter(INT32 NumRows,INT32 NumColumns) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: NumRows = num rows to base calc on NumColumns = num columns to base calc on Returns: Max gutter value Purpose: Dynamically calcs the max gutter value based on the given number of rows and columns, and the current paper size SeeAlso: - ******************************************************************************************/ INT32 PrintControl::CalcMaxGutter(INT32 NumRows,INT32 NumColumns) { double MinScaleFactor = double(MinPrintScale)/100; double PatchWidth = CalcPatchWidth(PaperWidth,NumColumns,0); double PatchHeight = CalcPatchHeight(PaperHeight,NumRows,0); INT32 MaxGutterWidth = INT32((PatchWidth - (double(PageWidth) *MinScaleFactor))+0.5); INT32 MaxGutterHeight = INT32((PatchHeight - (double(PageHeight)*MinScaleFactor))+0.5); if (MaxGutterWidth < MaxGutterHeight) return MaxGutterWidth; else return MaxGutterHeight; } /****************************************************************************************** > void PrintControl::CalcMultipleFit(INT32 NumRows,INT32 NumColumns,INT32 GutterVal,INT32 Wd,INT32 Ht) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: NumRows = num rows to fit on paper NumColumns = num columns to fit on paper GutterVal = gutter distance between each page Wd = Width of paper Ht = Height of paper Extra = An adjustment made to the page size (usually 0) Returns: - Purpose: Recalcs the scale factor required for each page to fit the specified number of rows and columns, and gutter distance, to the paper Dependants are: Scale ScaledWidth ScaledHeight SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::CalcMultipleFit(INT32 NumRows,INT32 NumColumns,INT32 GutterVal,INT32 Wd,INT32 Ht,INT32 Extra) { // Calc the width and height of each patch on the page, taking into account the given gutter value double PatchWidth = CalcPatchWidth(Wd,NumColumns,GutterVal); double PatchHeight = CalcPatchHeight(Ht,NumRows,GutterVal); // Work out the scale factor required to get the width of the page into this patch double ScaleFactor = PatchWidth / double(PageWidth+Extra); // Calc the new width and height of each page by applying the scale factor double NewWidth = PageWidth * ScaleFactor; double NewHeight= PageHeight * ScaleFactor; // If the scale factor made using the page width and patch width means that the page does NOT entirely // fit into a multiple-fit patch, then use the scale factor generated using the patch height and page height // // (NB: We add 1.0 to these values so that the '>' comparisons don't fail due to insignificant floating point errors). // if ((NewWidth > (PatchWidth+1.0)) || (NewHeight > (PatchHeight+1.0))) ScaleFactor = PatchHeight / double(PageHeight+Extra); #ifdef _DEBUG { // In theory, when the scale factor is applied to the page width and height, the page will fit // entirely into a patch. However, we still better check this is true when in debug builds NewWidth = PageWidth * ScaleFactor; NewHeight= PageHeight * ScaleFactor; if ((NewWidth > (PatchWidth+1.0)) || (NewHeight > (PatchHeight+1.0))) { ERROR3("Multiple fit scale factor does not fit page into patch"); } } #endif SetScaleFactor(ScaleFactor); // Use SetScaleFactor() to recalc ScaledWidth and ScaledHeight } /****************************************************************************************** > BOOL PrintControl::CalcFit() Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: - Returns: TRUE if a recalc took place, FALSE if nothing has been recalced Purpose: Recalcs the scale factor needed to fit the current page in the specified orientation, using the currently set fit type This will only do anything when UpdateDependants is TRUE SeeAlso: CalcMultipleFit() ******************************************************************************************/ BOOL PrintControl::CalcFit() { static BOOL IgnoreCall = FALSE; if (!UpdateDependants) return FALSE; if (IgnoreCall) // Stop re-entrant calls to this function return TRUE; IgnoreCall = TRUE; // Set these value to absolutely ziltch CropTopMargin=0; CropLeftMargin=0; switch (FitType) { case PRINTFIT_MULTIPLE: { INT32 PAWidth = PaperWidth; INT32 PAHeight = PaperHeight; INT32 CropAdjust = GetCropAdjust(); PAWidth -= (CropAdjust<<1); PAHeight -= (CropAdjust<<1); CalcMultipleFit(Rows,Columns,Gutter,PAWidth,PAHeight,0); // these settings just show to the user whats happening in the dialogue // they do not get used explicitly to position the pages. if ((Rows==1) && (Columns==1)) { LeftMargin = (PaperWidth -ScaledWidth) /2; TopMargin = (PaperHeight-ScaledHeight)/2; } } break; case PRINTFIT_BEST: { INT32 PAWidth = PrintableArea.Width(); INT32 PAHeight = PrintableArea.Height(); INT32 CropAdjust = GetCropAdjust(); PAWidth -= (CropAdjust<<1); PAHeight -= (CropAdjust<<1); BOOL PAOrient = ((double(PAWidth) / double(PAHeight)) <= 1.0); BOOL PageOrient = ((double(OrigPageWidth) / double(OrigPageHeight ))<= 1.0); PrintOrient NewOrient; if (PAOrient == PageOrient) NewOrient = PRINTORIENTATION_UPRIGHT; else NewOrient = PRINTORIENTATION_SIDEWAYS; if (NewOrient != Orient) SetPrintOrient(NewOrient); CalcMultipleFit(1,1,0,PAWidth,PAHeight,0); PAWidth += (CropAdjust<<1); PAHeight += (CropAdjust<<1); LeftMargin = PALeftMargin+((PAWidth -ScaledWidth) /2); TopMargin = PATopMargin +((PAHeight-ScaledHeight)/2); } break; case PRINTFIT_CUSTOM: { INT32 CropAdjust = GetCropAdjust(); CropLeftMargin = CropAdjust; CropTopMargin = CropAdjust; SetScale(Scale); } break; case PRINTFIT_BESTPAPER: // Best fit the document paper size onto the printed page // without scaling, distortion or clipping { INT32 PAWidth = PaperWidth; INT32 PAHeight = PaperHeight; INT32 CropAdjust = GetCropAdjust(); PAWidth -= (CropAdjust<<1); PAHeight -= (CropAdjust<<1); // Compute aspect of document and aspect of printed page // TRUE means rect is portrait orientation, taller than it is wide... BOOL PAOrient = (double(PAWidth) <= double(PAHeight)); BOOL PageOrient = (double(OrigPageWidth) <= double(OrigPageHeight)); PrintOrient NewOrient; if (PAOrient == PageOrient) NewOrient = PRINTORIENTATION_UPRIGHT; else NewOrient = PRINTORIENTATION_SIDEWAYS; if (NewOrient != Orient) SetPrintOrient(NewOrient); CropLeftMargin = CropAdjust; CropTopMargin = CropAdjust; SetScale(100.0); // PAWidth += (CropAdjust<<1); // PAHeight += (CropAdjust<<1); // Centre document page within printed page LeftMargin = (PAWidth - ScaledWidth) / 2; TopMargin = (PAHeight - ScaledHeight) / 2; } break; default: ERROR3_PF(("Unknown fit type (%d)",FitType)); IgnoreCall = FALSE; return FALSE; } IgnoreCall = FALSE; return TRUE; } /****************************************************************************************** > INT32 PrintControl::GetCropAdjust() const Author: Mike_Kenny (Xara Group Ltd) Created: 16/12/96 Inputs: - Returns: An INT32, the width of the crop area Purpose: Return the size of the extra area we need to take into account when fitting pages onto the printable paper. Currently the bleed size and crop area size is used. ******************************************************************************************/ INT32 PrintControl::GetCropAdjust() const { INT32 CropAdjust = 0; PrintMarksMan *pMarksMan = GetApplication()->GetMarksManager(); if (pMarksMan && Typesetting.OutputPrintersMarks()) CropAdjust = CropArea+Bleed; return CropAdjust; } /****************************************************************************************** > void PrintControl::AdjustForTypesetting() Author: Mike_Kenny (Xara Group Ltd) Created: 16/12/96 Inputs: - Returns: - Purpose: Adjust the printing variables to allow for typesetting marks to be positioned What happens here is that we adjust the X,Y translations so that we ensure a patch is moved into a position where we can get the crop marks between the patch and the papers edges. ******************************************************************************************/ /* void PrintControl::AdjustForTypesetting() { // Used to do it like this but don't anymore. #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) #ifndef STANDALONE PrintMarksMan *pMarksMan = GetApplication()->GetMarksManager(); if (pMarksMan && GetTypesetInfo()->OutputPrintersMarks()) { switch (FitType) { case PRINTFIT_MULTIPLE: { CropTopMargin = CropArea; CropLeftMargin = CropArea; // if the bleed is more than 1/2 of the gutter, then the // bleed will overflow the edge of the page by the difference! double sectw = CalcPatchWidth( PaperWidth, Columns,0); double secth = CalcPatchHeight(PaperHeight,Rows ,0); // Translate to the bottom left of the current patch double ovflx = Bleed - ((sectw - (double)ScaledWidth)/2); double ovfly = Bleed - ((secth - (double)ScaledHeight)/2); CropLeftMargin += (INT32)(ovflx+0.5); CropTopMargin += (INT32)(ovfly+0.5); } break; case PRINTFIT_BEST: { // does nothing at the moment. } break; case PRINTFIT_CUSTOM: { CropLeftMargin = CropArea+Bleed; CropTopMargin = CropArea+Bleed; } break; default: ERROR3_PF(("Unknown fit type (%d)",FitType)); break; } } #endif #endif } */ /****************************************************************************************** > BOOL PrintControl::SetRows(INT32 NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewVal = new number of coloumns of printed pages Returns: TRUE if new row num == NewVal, FALSE if it's had to be altered because NewVal is out of range Purpose: Sets the number of pages in each printed column, altering dependants automatically (unless importing) Dependants are: Scale ScaledWidth ScaledHeight Columns If not updating dependants, this will always return TRUE SeeAlso: StartImport() & EndImport() ******************************************************************************************/ BOOL PrintControl::SetRows(INT32 NewVal) { Rows = NewVal; if (UpdateDependants) { INT32 Max = CalcMaxRows(0); if (Rows < 1) Rows = 1; if (Rows > Max) Rows = Max; INT32 MaxGutter = CalcMaxGutter(Rows,Columns); if (Gutter > MaxGutter) Gutter = MaxGutter; CalcFit(); } return (Rows == NewVal); } /****************************************************************************************** > BOOL PrintControl::SetColumns(INT32 NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewVal = new number of coloumns of printed pages Returns: TRUE if new row num == NewVal, FALSE if it's had to be altered because NewVal is out of range Purpose: Sets the number of pages in each printed column, altering dependants automatically (unless importing) Dependants are: Scale ScaledWidth ScaledHeight Rows If not updating dependants, this will always return TRUE SeeAlso: StartImport() & EndImport() ******************************************************************************************/ BOOL PrintControl::SetColumns(INT32 NewVal) { Columns = NewVal; if (UpdateDependants) { INT32 Max = CalcMaxColumns(0); if (Columns < 1) Columns = 1; if (Columns > Max) Columns = Max; INT32 MaxGutter = CalcMaxGutter(Rows,Columns); if (Gutter > MaxGutter) Gutter = MaxGutter; CalcFit(); } return (Columns == NewVal); } /****************************************************************************************** > BOOL PrintControl::SetGutter(INT32 NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 10/4/95 Inputs: NewVal = new gutter measurement between each page Returns: TRUE if new row num == NewVal, FALSE if it's had to be altered because NewVal is out of range Purpose: Sets the gutter measurement, altering dependants automatically (unless importing) The gutter is the distance between each page when doing multiple fit printing. Half the gutter width is used as a margin for each page next to the edge of the paper Dependants are: Scale ScaledWidth ScaledHeight Rows Colunmns If not updating dependants, this will always return TRUE SeeAlso: StartImport() & EndImport() ******************************************************************************************/ BOOL PrintControl::SetGutter(INT32 NewVal) { Gutter = NewVal; if (UpdateDependants) { INT32 Max = CalcMaxGutter(1,1); if (Gutter < 0) Gutter = 0; if (Gutter > Max) Gutter = Max; INT32 MaxRows = CalcMaxRows(Gutter); if (Rows > MaxRows) Rows = MaxRows; INT32 MaxColumns = CalcMaxColumns(Gutter); if (Columns > MaxColumns) Columns = MaxColumns; CalcFit(); } return (Gutter == NewVal); } /****************************************************************************************** > void PrintControl::SetWholeSpread(BOOL State) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: State = new WholeSpread flag state Purpose: Sets the WholeSpread state, altering dependants automatically (unless importing) Dependants are: Scale ScaledWidth ScaledHeight PageWidth PageHeight Rows Columns SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetWholeSpread(BOOL State) { if (WholeSpread != State) { WholeSpread = State; if (UpdateDependants) { CalcPrintAreaVars(); // Update the page width & height (the page width either doubles or halves) SetRows(Rows); // Use SetRows() to recalc max rows and scale factor SetColumns(Columns); // Use SetColumns() to recalc max columns and scale factor } } } /****************************************************************************************** > void PrintControl::SetFitType(PrintFitType NewFitType) Author: Mark_Neves (Xara Group Ltd) Created: 11/4/95 Inputs: NewFitType = page fit type Purpose: Sets the fit type, altering dependants automatically (unless importing) Dependants are: ScaledWidth ScaledHeight Scale SeeAlso: StartImport() & EndImport() ******************************************************************************************/ void PrintControl::SetFitType(PrintFitType NewFitType) { FitType = NewFitType; if (UpdateDependants) CalcFit(); } /****************************************************************************************** > INT32 PrintControl::GetDotsPerInch() Author: Mark_Neves (Xara Group Ltd) Created: 18/4/95 Inputs: - Returns: DPI value used to render bitmaps Purpose: If the bitmap res setting is manual then the value the user entered is returned. If the bitmap res setting is automatic, then base the DPI on the printer's DPI Bitmap res = Half printer res if (Bitmap res > MAXAUTOBITMAPDPI) Bitmap res = MAXAUTOBITMAPDPI; if (Bitmap res < MINBITMAPDPI) Bitmap res = MINBITMAPDPI; SeeAlso: SetDotsPerInch(); ******************************************************************************************/ INT32 PrintControl::GetDotsPerInch() { // MRH 11/9/00 - Tidied up code to make it more readable // Basically the code checks to see if the auto flag is set. // If NOT set then the DotsPerInch variable is left with the value in the manual edit box. // If it is set then it gets the current printer resolution and divides it by 2! if (BitmapResolutionMethod == BITMAPRES_AUTO) { // Choose the DPI automatically // This is based on the printer resolution // Set up the local variable to the max auto dpi! INT32 PrinterDPI = MAXAUTOBITMAPDPI; // Get the printer resolution (if this fails, choose the maximum setting) if (!CCPrintDialog::GetResolution(&PrinterDPI)) PrinterDPI = MAXAUTOBITMAPDPI; // Failing could change the variable so reset it! // Make the DPI half the printer res DotsPerInch = PrinterDPI >> 1; // If this DPI value > MAXAUTOBITMAPDPI, then probably printing to a typesetter, in which case cap it as // there's no point in printing at any higher DPI if (DotsPerInch > MAXAUTOBITMAPDPI) DotsPerInch = MAXAUTOBITMAPDPI; // Make sure that it doesn't dip below the min. // If it does, choose the printer DPI, so that we ensure good quality for low DPI settings if (DotsPerInch < MINBITMAPDPI) DotsPerInch = PrinterDPI; } // return the new value! return DotsPerInch; } /****************************************************************************************** > void PrintControl::SetDotsPerInch(INT32 NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 18/4/95 Inputs: NewVal = DPI value Returns: - Purpose: Ensures the NewVal is not < MINBITMAPDPI If NewVal < MINBITMAP, the DPI is set to the printer's DPI SeeAlso: GetDotsPerInch() ******************************************************************************************/ void PrintControl::SetDotsPerInch(INT32 NewVal) { DotsPerInch = NewVal; if (DotsPerInch > MAXBITMAPDPI) DotsPerInch = MAXBITMAPDPI; if (DotsPerInch < MINBITMAPDPI) DotsPerInch = MINBITMAPDPI; /* if (DotsPerInch < MINBITMAPDPI) { INT32 PrinterDPI; // Get the printer resolution (if this fails, choose the minimum setting) if (!CCPrintDialog::GetResolution(&PrinterDPI)) PrinterDPI = MINBITMAPDPI; DotsPerInch = PrinterDPI; } */ } /****************************************************************************************** > PrintMethodType PrintControl::GetPrintMethod(PrintMethodType NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 20/7/95 Inputs: - Returns: The app's current print method Purpose: Returns the app's print method. This is stored in the global var AppPrintMethod SeeAlso: SetPrintMethod() ******************************************************************************************/ PrintMethodType PrintControl::GetPrintMethod() { return AppPrintMethod; } /****************************************************************************************** > void PrintControl::SetPrintMethod(PrintMethodType NewVal) Author: Mark_Neves (Xara Group Ltd) Created: 20/7/95 Inputs: NewVal = new print method Returns: - Purpose: Sets the app's print method to be NewVal This is stored in the global var AppPrintMethod SeeAlso: GetPrintMethod() ******************************************************************************************/ void PrintControl::SetPrintMethod(PrintMethodType NewVal) { AppPrintMethod = NewVal; } /****************************************************************************************** > void PrintControl::GetObjPrintRange() Author: Mark_Neves (Xara Group Ltd) Created: 22/7/96 Inputs: - Returns: PRINTRANGEOBJ_ALL or PRINTRANGEOBJ_SELECTED Purpose: Find out the object range the user wants to print to. This function has been modified (today 22/7/96) so that it reacts to the current selection. This is to fix bug 4857, which meant if you selected "print selected objects" then deselected all the objects, it would still print the selected objects, resulting in a blank page. What's worse, the UI in the print dlg would grey out, so you couldn't switch it off. This routine will mean that "print all" is on if the internal var is PRINTRANGEOBJ_ALL OR there are no selected objects. SeeAlso: GetPrintMethod() ******************************************************************************************/ PrintRangeObj PrintControl::GetObjPrintRange() { // Find the selection SelRange* pSelRange = GetApplication()->FindSelection(); if (pSelRange->FindFirst() != NULL) return ObjPrintRange; // There are selected objects, so return the setting the user has made. else return PRINTRANGEOBJ_ALL; // There's no selected objects, so always print all objects. } //-------------------------------------------------------------------------- // Print layout funcs /****************************************************************************************** > BOOL PrintControl::CalcNumPaper() Author: Mark_Neves (Xara Group Ltd) Created: 18/4/95 Inputs: - Outputs: NumPaper = The number of pieces of paper we will print to Returns: TRUE if it was able to cal num paper to print to, FALSE otherwise Purpose: This works out how many pieces of paper we will print to. NB: This can be different to the number of pieces of paper that comes out of the printer when the printer can do multiple copies and we are in a position to exploit this It takes into account DPS, whole spread & left or right-only settings. It also takes into account the collated flag & the ability of the printer to do multiple copies. The number of pieces of paper that the printer will produce at the end of the print job = number of printable pages * num copies If the output is colla SeeAlso: GetDotsPerInch() ******************************************************************************************/ BOOL PrintControl::CalcNumPaper() { BOOL CanMultiCopy=TRUE; // WEBSTER-ranbirr-13/11/96 #ifndef WEBSTER // Can the printer do multiple copies? if (!CCPrintDialog::CanMultiCopy(&CanMultiCopy)) return FALSE; #endif //webster INT32 NumActualPiecesOfPaper = NumPrintablePages * NumCopies; // Num pieces of paper that will come out of printer // NumPaper will be the number of pieces of paper we will print to // Default to the number printable of pages NumPaper = NumPrintablePages; if (NumPrintablePages == 1) { // If the printer can't cope with multiple copies, we'll have to do them all if (!CanMultiCopy) NumPaper = NumActualPiecesOfPaper; } else { // If the printer can't cope with multiple copies OR we need to collate the output // we'll have to do them all if (Collated || !CanMultiCopy) NumPaper = NumActualPiecesOfPaper; } return TRUE; } /******************************************************************************************** > BOOL PrintControl::StartPrinting() Author: Mark_Neves (Xara Group Ltd) Created: 25/4/95 Inputs: - Returns: TRUE if all OK, FALSE otherwise Purpose: This informs the print info object that you are about to do some printing. This is purely to set up the print layout mechanism. It will work out how many pieces of paper will be printed to, and how many times the page will be printed on each piece of of paper (for multiple fit printing). The mechanism works like this: if (StartPrinting()) { while (GetNextPaper()) { while (GetNextPatch()) { Use access funcs to get hold of data set up by GetNextPath(), e.g. scale, translation, etc if (SelectedOnly) print all selected objects that lie within the ClipRect area in the spread else print all objects that lie within the ClipRect area in the spread } } EndPrinting() } SeeAlso: GetNextPaper(), GetNextPath(), EndPrinting() ********************************************************************************************/ BOOL PrintControl::StartPrinting() { ERROR2IF(Printing,FALSE,"Already printing - have you called EndPrinting()?"); ERROR2IF(!PrintAreaSetUp,FALSE,"The print control hasn't been set up via SetUp()"); ERROR2IF(pSpread == NULL,FALSE,"The print control pSpread is NULL"); // Find out the number of printable pages NumPrintablePages = GetNumPrintablePages(); // This will be either 1 or 2 // Init NumPaper member var with the number of pieces of paper we will print to. if (!CalcNumPaper()) return FALSE; // PaperNumber is the number of the current piece of paper being printed to. // MaxPaperNumber is the total number of pieces of paper we will print to. PaperNumber = 0; // incremented at the start of GetNextPaper() MaxPaperNumber = NumPaper; Reprint = FALSE; // Set to TRUE by ReprintPaper() to make GetNextPaper() to return // the same paper again NumPatches = 0; Printing = TRUE; SelRange* pSelRange = GetApplication()->FindSelection(); SelectionPresent = (pSelRange->FindFirst() != NULL); // Now make sure that the list of printing plates is updated in case any spot colours // have been created or deleted recently... TypesetInfo* tpInfo = GetTypesetInfo(); if (tpInfo != NULL && tpInfo->AreSeparating()) { // Call CreatePlateList to ensure that the list of printing plates is set up // This will just update the list (if necessary) if it has been previously created, // to make sure that screening options and present plates are all hunky-dory. tpInfo->CreatePlateList(); } return TRUE; } /******************************************************************************************** > BOOL PrintControl::EndPrinting() Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: - Returns: TRUE if all OK, FALSE otherwise Purpose: This informs the print info object that you have finished printing. SeeAlso: StartPrinting(); ********************************************************************************************/ BOOL PrintControl::EndPrinting() { ERROR2IF(!Printing,FALSE,"Not printing - have you called StartPrinting()?"); Printing = FALSE; return TRUE; } /******************************************************************************************** > BOOL PrintControl::GetNextPaper() Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: - Returns: TRUE if you should print on another piece of paper FALSE if the print job should end Purpose: Call this for each piece of paper to be printed to. NB: You must call StartPrinting() before calling this func as part of your print loop If ReprintPaper() is called after GetNextPaper(), then the next time you call GetNextPaper() you will actually be printing the previous piece of paper e.g while (GetNextPaper()) // Infinite loop ReprintPaper(); SeeAlso: StartPrinting(),EndPrinting(), ReprintPaper() ********************************************************************************************/ BOOL PrintControl::GetNextPaper() { ERROR2IF(!Printing,FALSE,"Not printing - have you called StartPrinting()?"); // Do we need to reprint the same piece of paper? if (Reprint) { // Only re-jig the counters if we have called GetNextPaper() at least once if (NumPaper < MaxPaperNumber) { NumPaper++; PaperNumber--; } // Reprinting, so set flag to FALSE Reprint = FALSE; } if (NumPaper > 0) { NumPaper--; PaperNumber++; // Calc the number of patches we'll have to print on this next piece of paper if (FitType == PRINTFIT_MULTIPLE) { NumPatches = Rows*Columns; // PatchRow & PatchColumn form a coordinate specifying which patch to print next PatchRow = 0; PatchColumn = 0; // Section width and height define the size of the areas of the page patches will fit into. // Effectively these are the patch sizes ignoring the gutter value. // Each patch is centred within a section of the page. INT32 CropAdjust = GetCropAdjust(); INT32 PAWidth = PaperWidth - (CropAdjust<<1); INT32 PAHeight = PaperHeight - (CropAdjust<<1); SectionWidth = INT32(CalcPatchWidth(PAWidth, Columns,0)); SectionHeight = INT32(CalcPatchHeight(PAHeight,Rows, 0)); } else NumPatches = 1; // PatchNumber is the number of the current patch being printed to. // MaxPatchNumber is the total number of patches printed on this piece of paper PatchNumber = 0; // incremented at the start of GetNextPatch() MaxPatchNumber = NumPatches; // Calc the object clip rect used to define which objects within the total printable area should // be printed on this piece of paper // // Default to the total printable area PatchClipRect = TotalPrintArea; if (NumPrintablePages > 1) { // The number of printable pages > 1 (i.e. we have a double page spread, we are printing // both left & right pages, and printing individual pages) INT32 m; if (Collated) { // If collated output, then oscillate the clip rect // between the left and right page, controlled by the current paper number m = (PaperNumber-1) % NumPrintablePages; } else { // Otherwise, print 'n' left pages followed by 'n' right pages m = (PaperNumber-1) / (MaxPaperNumber / NumPrintablePages); } PatchClipRect.lo.x += (OrigPageWidth*m); PatchClipRect.hi.x = PatchClipRect.lo.x + OrigPageWidth; } else { if (DPS && !WholeSpread && (DPSPrintRange != PRINTRANGEDPS_BOTH)) { // Here we have a DPS, we are printing individual pages, but we are either // printing left-only or right-only pages // // So if right only, add the page width to the lo.x coord to move the area to the right hand side. // In either case, the patch clip rect hi.x will be lo.x+OrigPageWidth. if (DPSPrintRange == PRINTRANGEDPS_RIGHTPAGES) PatchClipRect.lo.x += OrigPageWidth; PatchClipRect.hi.x = PatchClipRect.lo.x + OrigPageWidth; } } // take into account the bleed margin /* PatchClipRect.Inflate(Bleed); if (Orient == PRINTORIENTATION_SIDEWAYS) PatchClipRect.Translate(-Bleed,Bleed); else PatchClipRect.Translate(Bleed,Bleed); */ return TRUE; } return FALSE; } /******************************************************************************************** > BOOL PrintControl::MorePaper() Author: Mike_Kenny (Xara Group Ltd) Created: 11/6/96 Inputs: - Returns: TRUE if there is more paper to come FALSE if there's no more paper. Purpose: Call this for each piece of paper to be printed to. ********************************************************************************************/ BOOL PrintControl::MorePaper() { if (Reprint && NumPaper < MaxPaperNumber) return TRUE; return (NumPaper > 0); } /******************************************************************************************** > BOOL PrintControl::ReprintPaper() Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: - Returns: TRUE if all OK, FALSE otherwise Purpose: This allows you to print on the same piece of paper again. If you call this func after a call to GetNextPaper(), then the next time you call GetNextPaper() you will actually be starting the print on the same piece of paper. SeeAlso: GetNextPaper() ********************************************************************************************/ BOOL PrintControl::ReprintPaper() { Reprint = TRUE; return TRUE; } /******************************************************************************************** > BOOL PrintControl::GetNextPatch(PrintPatchInfo* pPatchInfo) Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: pPatchInfo = ptr to object to store patch info in Outputs: - Returns: TRUE if you should print another page on the paper FALSE if the piece of paper printed to is finished. Purpose: Each time this func returns TRUE, print the page using the data set up by this call. If this call returns TRUE, the the given PrintPatchInfo has been set up with all the data needed to print the given patch. NB: You must call GetNextPaper() before calling this func as part of your print loop SeeAlso: StartPrinting(), GetNextPaper(), EndPrinting() ********************************************************************************************/ BOOL PrintControl::GetNextPatch(PrintPatchInfo* pPatchInfo) { ERROR2IF(!Printing,FALSE,"Not printing - have you called StartPrinting()?"); ERROR2IF(pPatchInfo == NULL,FALSE,"Given NULL pPatchInfo param"); if (NumPatches > 0) { NumPatches--; PatchNumber++; pPatchInfo->pSpread = pSpread; pPatchInfo->Scale = Scale; pPatchInfo->ClipRect = PatchClipRect; pPatchInfo->Rotate = (Orient == PRINTORIENTATION_SIDEWAYS); pPatchInfo->SelectedOnly = ((ObjPrintRange == PRINTRANGEOBJ_SELECTED) && SelectionPresent); pPatchInfo->VisibleLayers = (Layers == PRINTLAYERS_VISIBLEFOREGROUND); pPatchInfo->XTrans = 0; pPatchInfo->YTrans = 0; pPatchInfo->PaperWidth = PaperWidth; pPatchInfo->PaperHeight = PaperHeight; pPatchInfo->ScaledWidth = ScaledWidth; pPatchInfo->ScaledHeight = ScaledHeight; pPatchInfo->Bleed = Bleed; pPatchInfo->CropArea = CropArea; pPatchInfo->PaperNumber = PaperNumber; pPatchInfo->MaxPaperNumber = MaxPaperNumber; pPatchInfo->PatchNumber = PatchNumber; pPatchInfo->MaxPatchNumber = MaxPatchNumber; pPatchInfo->PALeftMargin = PALeftMargin; pPatchInfo->PATopMargin = PATopMargin; // set emulsion up/down for print rendering TypesetInfo* tpInfo = GetTypesetInfo(); pPatchInfo->EmulsionDown = ( (tpInfo != NULL) && tpInfo->PrintEmulsionDown() ); switch (FitType) { case PRINTFIT_BEST: // Move it to the right by LeftMargin, and down by TopMargin pPatchInfo->XTrans = LeftMargin; pPatchInfo->YTrans = (PaperHeight-ScaledHeight)-TopMargin; break; case PRINTFIT_BESTPAPER: // Move it to the right by LeftMargin, and down by TopMargin pPatchInfo->XTrans = LeftMargin; pPatchInfo->YTrans = (PaperHeight-ScaledHeight)-TopMargin; pPatchInfo->XTrans += CropLeftMargin; pPatchInfo->YTrans -= CropTopMargin; break; case PRINTFIT_CUSTOM: { // Move it to the right by LeftMargin, and down by TopMargin pPatchInfo->XTrans = LeftMargin; pPatchInfo->YTrans = (PaperHeight-ScaledHeight)-TopMargin; pPatchInfo->XTrans += CropLeftMargin; pPatchInfo->YTrans -= CropTopMargin; } break; case PRINTFIT_MULTIPLE: { // Translate to the bottom left of the current patch INT32 CropAdjust = GetCropAdjust(); pPatchInfo->XTrans = CropAdjust + (SectionWidth * PatchColumn) + ((SectionWidth - ScaledWidth)/2); pPatchInfo->YTrans = CropAdjust + (SectionHeight * PatchRow) + ((SectionHeight - ScaledHeight)/2); PatchColumn += 1; if (PatchColumn >= Columns) { PatchColumn = 0; PatchRow += 1; } } break; default: ERROR3_PF(("Unknown fit type : %d",FitType)); break; } return TRUE; } return FALSE; } /******************************************************************************************** > BOOL PrintControl::StartPlatePrinting(PrintView *pPrintView, UINT32 *const pErrNo) Author: Mike_Kenny (Xara Group Ltd) Created: 11/6/96 Inputs: pPrintView - The View to which we are rendering Outputs: errno - Returns: - Purpose: This function makes sure the plate printing loop is initialised for the next set of pages on a single sheet of paper to pass through the driver. It sets up an appropriate ColourPlate and ColourCOntextCMYK for the given PrintView. ********************************************************************************************/ BOOL PrintControl::StartPlatePrinting(PrintView *pPrintView, UINT32 *const pErrNo) { // Clear the ouput error first (*pErrNo)=0; // If there's no view, drawing will be rather tricky if (pPrintView == NULL) { ERROR3("Sanity check, The view is NULL during StartPlatePrinting!"); return FALSE; } // Get hold of the resident colour management system ColourContext *pContext; PORTNOTE("cms", "Disabled XaraCMS"); #ifndef EXCLUDE_FROM_XARALX XaraCMS* ptheCMS=GetApplication()->GetCMSManager(); if (ptheCMS!=NULL) { // First try to set the printer context specified in the ini file read // when we started up String_256 PrintProfile; ptheCMS->GetPrinterProfile(&PrintProfile); pContext = new ColourContextCMYK(pPrintView, &PrintProfile); if (pContext==NULL) { // We need to error here and inform the user we // are out of memory ERROR3("Failed to create a CMYK colour context during print initialisation in SetNextPlate()"); (*pErrNo) = _R(IDS_OUT_OF_MEMORY); return FALSE; } if (!(pContext->IsDeviceContext())) { // Eeek, we failed to build the physical device context // which means something rather nasty went on. We must now // warn the user. They can either continue with a logical // context or abort the proceedings. // TO DO: Make this a nice resourced string! // Hang about, we should attempt to use a printer.xcms down // the root directory of Camelot, lets see if we can find that delete pContext; pContext=NULL; ptheCMS->GetDefaultPrinterProfile(&PrintProfile); pContext = new ColourContextCMYK(pPrintView, &PrintProfile); // if we've failed again if (pContext==NULL) { ERROR3("Failed to create a CMYK colour context during print initialisation in SetNextPlate()"); (*pErrNo) = _R(IDS_OUT_OF_MEMORY); return FALSE; } // ok if we've still failed to locate even this we really are stuck and will have to use the context // in logical mode, but lets ask the user about this first. if (!(pContext->IsDeviceContext())) { ErrorInfo Info; Info.ErrorMsg = _R(IDT_OPTS_LOGICALCONTEXT); Info.Button[0] = _R(IDS_CONTINUE); Info.Button[1] = _R(IDS_CANCEL); if (AskQuestion(&Info) == _R(IDS_CANCEL)) { (*pErrNo) = _R(IDS_PRINT_USERTERM); return FALSE; } } } } else #endif { // Create a logical colour context. This isn't strictly necessary, as the view will default to // using the global default (logical) context anyway, but we might as well be safe pContext = new ColourContextCMYK(pPrintView); if (pContext==NULL) { // we've failed to create a new colour context for this document // We must abort the printing loop ERROR3("Failed to create a CMYK colour context during print initialisation in SetNextPlate()"); (*pErrNo) = _R(IDS_OUT_OF_MEMORY); return FALSE; } } // Set the new context in the view. The view will delete it when it's done with it // NOTE that the view will attach its own ColourPlate to this context, so there is no need // (indeed, no point whatsoever) for us to try to set that up for it. pPrintView->SetColourContext(COLOURMODEL_CMYK, pContext); // Set up the plate printing system, we do this for composite and separated output Typesetting.InitPlatesForPrinting(); return TRUE; } /******************************************************************************************** > void PrintControl::EndPlatePrinting(PrintView *pPrintView) Author: Mike_Kenny (Xara Group Ltd) Created: 11/6/96 Inputs: - Returns: - Purpose: This function makes sure the plate printing loop is shut down correctly. We need to make sure that the last plate is detached from the colour context inside the print view, otherwise when the print view is destroyed the plate in the colour context in the print view will be destroyed. As our printer dialogue keeps this in its list, we need to make sure it only gets deleted once during that lists destruction. ********************************************************************************************/ void PrintControl::EndPlatePrinting(PrintView *pPrintView) { // If there's no view, drawing will be rather tricky if (pPrintView == NULL) { ERROR3("Sanity check, The view is NULL during StartPlatePrinting!"); return; } pPrintView->SetColourContext(COLOURMODEL_CMYK, NULL); } /******************************************************************************************** > BOOL PrintControl::MorePlates() Author: Mike_Kenny (Xara Group Ltd) Created: 11/6/96 Inputs: - Returns: TRUE if there is more plates to come FALSE if there's no more plates. Purpose: Call this to determin whether there are more plates to print during this separation. ********************************************************************************************/ BOOL PrintControl::MorePlates() { return (Typesetting.NumPrintPlatesRemaining() > 0); } /******************************************************************************************** > void PrintControl::SetNextPlate(PrintView *pPrintView) Author: Mike_Kenny (Xara Group Ltd) Created: 11/6/96 Inputs: pPrintView = a pointer to the print view class. Returns: - Purpose: Call this to set up the view related data ready for the next plate rendering ********************************************************************************************/ BOOL PrintControl::SetNextPlate(PrintView *pPrintView) { // If there's no view, drawing will be rather tricky if (pPrintView == NULL) { ERROR3("Sanity check, The view is NULL during SetNextPlate!"); return FALSE; } // If we are not separating then do nothing but make sure // we force MorePlates() to terminate properly the next time // around. if (!Typesetting.AreSeparating()) { Typesetting.SetNextCompositePlate(); return TRUE; } // Find the next printing plate. We need to call this to decrement // the plate printing count and other such unsightlyness so that MorePlates // executes correctly. ColourPlate *pPrintPlate = Typesetting.GetNextPrintPlate(); if (pPrintPlate==NULL) { // There are no more plates left to print. MorePlates() has // failed in its duty and should be shot. return FALSE; } // We now need to set this plate in the print view in order // to describe the separation correctly, this should be pretty easy // if we can get a hold of the print view of course. pPrintView->SetColourPlate(pPrintPlate); return TRUE; } /******************************************************************************************** > void PrintControl::RenderRect(RenderRegion* pRRegion,DocRect Rect,BOOL Fill) Author: Mark_Neves (Xara Group Ltd) Created: 9/5/95 Inputs: pRRegion = ptr to a render region Rect = rect to redraw Fill = TRUE if filled, FALSE if empty Outputs: - Returns: - Purpose: Renders the rect given SeeAlso: RenderPrintBorders() ********************************************************************************************/ void PrintControl::RenderRect(RenderRegion* pRRegion,DocRect Rect,BOOL Fill) { if (Rect.IsValid() && !Rect.IsEmpty()) { if (Fill) pRRegion->DrawRect(&Rect); else pRRegion->DrawPixelRect(&Rect); } } /******************************************************************************************** > void PrintControl::RenderPrintBorder(RenderRegion* pRRegion) Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: pRRegion = ptr to a render region Outputs: - Returns: - Purpose: Renders the printable area on the spread according to the current print layout method. SeeAlso: StartPrinting(), GetNextPaper(), EndPrinting() Note: As we are being given a render region that may be in the background redraw list, forcing a redraw of documents is very bad as this **MAY** delete the render region we hae been given. This used to happen if setup hadn't been called before when routine was entered for the first time. ********************************************************************************************/ void PrintControl::RenderPrintBorder(RenderRegion* pRRegion) { if (SetUpFailed) return; BOOL DrawBorders = FALSE; switch (FitType) { // Always try and show print borders for these fit types case PRINTFIT_BEST: case PRINTFIT_BESTPAPER: case PRINTFIT_CUSTOM: DrawBorders = TRUE; break; // Only try and show print borders for multiple fit when doing 1 row by 1 column case PRINTFIT_MULTIPLE: DrawBorders = ((Rows == 1) && (Columns == 1)); break; default: ERROR3_PF(("Unknown fit type (%d)",FitType)); break; } // If we can draw borders for this fit type, ensure that the relevent info is available to do so if (DrawBorders) { // Neville 29/8/97 // As we are being passed a render region and so might be in the background redraw // loop, we must not force a redraw of the doc if we haven't called set up before. // If we do then this render region may be deleted and we wont get told about it. // This is bad! e.g. Load document with print borders set and have a font replacement // message go off. if (!PrintAreaSetUp) DrawBorders = SetUp(Document::GetSelectedSpread(), FALSE); else DrawBorders = SetUp(pSpread, FALSE); } // If the fit type is right, and we have all the info, draw the borders if (DrawBorders) { double ScaleFactor = 100.0 / Scale.MakeDouble(); INT32 ScaledPaperWidth = INT32(double(PaperWidth) *ScaleFactor); INT32 ScaledPaperHeight = INT32(double(PaperHeight)*ScaleFactor); INT32 ScaledPAWidth = INT32(double(PrintableArea.Width()) *ScaleFactor); INT32 ScaledPAHeight = INT32(double(PrintableArea.Height())*ScaleFactor); INT32 ScaledPALeftMargin = INT32(double(PALeftMargin)*ScaleFactor); INT32 ScaledPATopMargin = INT32(double(PATopMargin) *ScaleFactor); INT32 ScaledLeftMargin = INT32(double(LeftMargin) *ScaleFactor)+CropLeftMargin; INT32 ScaledTopMargin = INT32(double(TopMargin) *ScaleFactor)+CropTopMargin; INT32 StartPageNum = 0; // We're starting from page 0 (the left page) by default INT32 NumPages = GetNumPrintablePages(); // Find out how many we need to print // If we're only printing the right page, then start from page 1 (the right page) // and increment the number of pages by 1 (i.e. the loop terminating value) // This will make sure that the print borders get drawn over the right page if ((NumPages == 1) && (DPSPrintRange == PRINTRANGEDPS_RIGHTPAGES)) { StartPageNum = 1; NumPages++; } for (INT32 PageNum = StartPageNum;PageNum < NumPages;PageNum++) { StockColour PaperCol = COLOUR_YELLOW; StockColour PrAreaCol = COLOUR_RED; if (PageNum > 0) { PaperCol = COLOUR_GREEN; PrAreaCol = COLOUR_BLUE; } // PagePrintArea defines the portion of the spread that is printable (this // is either the whole spread, or a single page when printing DPS & individual pages) DocRect PagePrintArea = TotalPrintArea; PagePrintArea.lo.x += OrigPageWidth*PageNum; PagePrintArea.hi.x = PagePrintArea.lo.x + OrigPageWidth; PagePrintArea.hi.y = PagePrintArea.lo.y + OrigPageHeight; // PrbleArea will define the printable area in relation to the current spread DocRect PrbleArea = PagePrintArea; // PaperArea represents the total area of the paper in the printer DocRect PaperArea; // If printing sideways, the width and height of the printable area should be swapped if (Orient == PRINTORIENTATION_SIDEWAYS) { PrbleArea.hi.x = PrbleArea.lo.x+ScaledPAHeight; PrbleArea.hi.y = PrbleArea.lo.y+ScaledPAWidth; PrbleArea.Translate(ScaledPATopMargin,ScaledPALeftMargin); PrbleArea.Translate(-ScaledTopMargin,-ScaledLeftMargin); PaperArea = PrbleArea; PaperArea.Translate(-ScaledPATopMargin,-ScaledPALeftMargin); PaperArea.hi.x = PaperArea.lo.x + ScaledPaperHeight; PaperArea.hi.y = PaperArea.lo.y + ScaledPaperWidth; } else { PrbleArea.hi.x = PrbleArea.lo.x+ScaledPAWidth; PrbleArea.lo.y = PrbleArea.hi.y-ScaledPAHeight; PrbleArea.Translate(ScaledPALeftMargin,-ScaledPATopMargin); PrbleArea.Translate(-ScaledLeftMargin,ScaledTopMargin); PaperArea = PrbleArea; PaperArea.Translate(-ScaledPALeftMargin,ScaledPATopMargin); PaperArea.hi.x = PaperArea.lo.x + ScaledPaperWidth; PaperArea.lo.y = PaperArea.hi.y - ScaledPaperHeight; } // We need to draw four grey slabs that show the areas on the page that will // not be printed pRRegion->SetLineColour(COLOUR_NONE); pRRegion->SetFillColour(COLOUR_MIDGREY); DocRect Slab = PagePrintArea; Slab.hi.x = PrbleArea.lo.x; RenderRect(pRRegion,Slab,TRUE); Slab = PagePrintArea; Slab.lo.x = PrbleArea.hi.x; RenderRect(pRRegion,Slab,TRUE); Slab = PagePrintArea; Slab.hi.y = PrbleArea.lo.y; RenderRect(pRRegion,Slab,TRUE); Slab = PagePrintArea; Slab.lo.y = PrbleArea.hi.y; RenderRect(pRRegion,Slab,TRUE); pRRegion->SetFillColour(COLOUR_BLACK); RenderRect(pRRegion,PagePrintArea,FALSE); pRRegion->SetFillColour(PrAreaCol); RenderRect(pRRegion,PrbleArea,FALSE); pRRegion->SetFillColour(PaperCol); RenderRect(pRRegion,PaperArea,FALSE); } } } /******************************************************************************************** > BOOL PrintControl::RedrawPrintableArea(DocView* pDocView) Author: Mark_Neves (Xara Group Ltd) Created: 10/5/95 Inputs: pDocView - ptr to DocView to redraw Outputs: - Returns: - Purpose: This func can be passed as a param to Document::ForceRedraw() and hence can control which views get redraw. This func ensures that only views that are showing print borders get redrawn. SeeAlso: StartPrinting(), GetNextPaper(), EndPrinting() ********************************************************************************************/ BOOL PrintControl::RedrawPrintableArea(DocView* pDocView) { if (pDocView->GetShowPrintBorders()) return(TRUE); ColourPlateType PlateType = COLOURPLATE_NONE; if (pDocView->GetColourPlate() && !pDocView->GetColourPlate()->IsDisabled()) PlateType = pDocView->GetColourPlate()->GetType(); return(PlateType != COLOURPLATE_NONE && PlateType != COLOURPLATE_COMPOSITE); } //------------------------------------------------------------ //------------------------------------------------------------ //------------------------------------------------------------ /****************************************************************************************** > PrintPatchInfo::PrintPatchInfo() Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: - Outputs: - Returns: - Purpose: Default constructor Errors: - SeeAlso: - ******************************************************************************************/ PrintPatchInfo::PrintPatchInfo() { Scale = FIXED16(100); XTrans = 0; YTrans = 0; ClipRect = DocRect(0,0,0,0); Rotate = FALSE; SelectedOnly = FALSE; EmulsionDown = FALSE; VisibleLayers = TRUE; pSpread = NULL; PaperWidth = 0; PaperHeight = 0; PaperNumber = 0; MaxPaperNumber = 0; PatchNumber = 0; MaxPatchNumber = 0; }; /****************************************************************************************** > PrintPatchInfo::~PrintPatchInfo() Author: Mark_Neves (Xara Group Ltd) Created: 26/4/95 Inputs: - Outputs: - Returns: - Purpose: Default deconstructor Errors: - SeeAlso: PrintPatchInfo()::PrintPatchInfo() ******************************************************************************************/ PrintPatchInfo::~PrintPatchInfo() { // Does nowt as yet } /****************************************************************************************** > DocRect PrintPatchInfo::GetClipRect(BOOL AddBleed, BOOL AddCropArea) Author : Mike Created : 11/6/95 Inputs : AddBleed = Inflate the output clip rectangle by the bleed value AddCropArea = Inflate the output clip rectangle by the crop area Returns : A clip rectangle. Purpose : Return the value of the clip rectangle held in this structure. The clip rectangle is defined to fit snuggly around a page. No other inflations should or do occur around this clip rectangle. However the printing mechanism needs to know about bleed sizes and cropmark areas in order to render and clip objects correctly so it uses inflated rectangles on occasions. It should not and cannot inflate rectangles itself however because this would assume knowledge of patch positioning which only the printcontrol class knows anything about. ******************************************************************************************/ DocRect PrintPatchInfo::GetClipRect(BOOL AddBleed, BOOL AddCropArea) const { DocRect Temp = ClipRect; InflateRectBy(&Temp, AddBleed, AddCropArea); return Temp; } void PrintPatchInfo::InflateRectBy(DocRect *pRect, BOOL AddBleed, BOOL AddCropArea) const { if (AddBleed) pRect->Inflate(Bleed); if (AddCropArea) pRect->Inflate(CropArea); } void PrintPatchInfo::InflateRectBy(OilRect *pRect, BOOL AddBleed, BOOL AddCropArea) const { if (AddBleed) pRect->Inflate(Bleed); if (AddCropArea) pRect->Inflate(CropArea); } void PrintPatchInfo::DeflateRectBy(DocRect *pRect, BOOL AddBleed, BOOL AddCropArea) const { if (AddBleed) pRect->Inflate(-Bleed); if (AddCropArea) pRect->Inflate(-CropArea); } MILLIPOINT PrintPatchInfo::GetBleed() const { return Bleed; } MILLIPOINT PrintPatchInfo::GetCropArea() const { return CropArea; } /****************************************************************************************** > TypesetInfo::TypesetInfo() Author : Mike Created : 11/6/95 Purpose : The default constructor for the typesetting class. We use this class to define the typesetting requirements of the next print run. ******************************************************************************************/ TypesetInfo::TypesetInfo() { MakeSeparations = FALSE; PrintResolution = 300; ScreenFrequency = 60.0; DefaultScreenType = SCRTYPE_SPOT1; UseScreening = FALSE; ShowPrintersMarks = FALSE; EmulsionDown = FALSE; PhotoNegative = FALSE; OverprintBlack = FALSE; NumPrintPlates = 0; CurrPrintPlateNum = 0; CurrentPlate = NULL; CurrentPrintPlate = NULL; } /****************************************************************************************** > TypesetInfo::~TypesetInfo() Author : Mike Created : 11/6/95 Purpose : The destructor. We must remove all items from our PrintingPlates list and delete them, otherwise the base list class will complain profusely. ******************************************************************************************/ TypesetInfo::~TypesetInfo() { DestroyPlateList(); } /****************************************************************************************** > static TypesetInfo *TypesetInfo::FindTypesetInfoForDoc(Document *pDoc = NULL); Author : Jason Created : 15/8/96 Inputs : pDoc = NULL (to look in selected doc) or the document to find the info for Returns : NULL, or the selected doc's TypesetInfo Purpose : Conveniently find the typeset info for the given document ******************************************************************************************/ TypesetInfo *TypesetInfo::FindTypesetInfoForDoc(Document *pDoc) { if (pDoc == NULL) pDoc = Document::GetSelected(); ERROR2IF(pDoc == NULL, NULL, "No document to find typeset info for!"); // Find the doc's print component PrintComponent *pPrComp = (PrintComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(PrintComponent)); ERROR2IF(pPrComp == NULL, NULL, "Can't find a document's print component"); // Find a ptr to the print component's print control object PrintControl* pPrCtrl = pPrComp->GetPrintControl(); ERROR2IF(pPrCtrl == NULL, NULL, "The doc's print component gave me a NULL print control object"); TypesetInfo *pTInfo = pPrCtrl->GetTypesetInfo(); ERROR2IF(pTInfo == NULL, NULL, "The doc's print control object gave me a NULL TypesetInfo object"); return(pTInfo); } /****************************************************************************************** > TypesetInfo& TypesetInfo::operator=(TypesetInfo& other) Author : Jason Created : 17/9/96 Inputs : other - the TypesetInfo object to copy Returns : the copy (this) Purpose : TypesetInfo assignment operator ******************************************************************************************/ TypesetInfo& TypesetInfo::operator=(TypesetInfo& other) { MakeSeparations = other.MakeSeparations; PrintResolution = other.PrintResolution; ScreenFrequency = other.ScreenFrequency; DefaultScreenType = other.DefaultScreenType; UseScreening = other.UseScreening; ShowPrintersMarks = other.ShowPrintersMarks; EmulsionDown = other.EmulsionDown; PhotoNegative = other.PhotoNegative; OverprintBlack = other.OverprintBlack; PrintSpotAsProcess = other.PrintSpotAsProcess; // Now copy the plate list // First, vape all pointers to default values CurrPrintPlateNum = 0; CurrentPlate = NULL; CurrentPrintPlate = NULL; // Now destroy any plates we may have already DestroyPlateList(); ColourPlate *pPlate = other.GetFirstPlate(); while (pPlate != NULL) { ColourPlate *pNewPlate = new ColourPlate(*pPlate); if (pNewPlate == NULL) break; AddPlate(pNewPlate); pPlate = other.GetNextPlate(pPlate); } return(*this); } /****************************************************************************************** > BOOL TypesetInfo::GetScreenName(ScreenType type, StringBase *pString) Author : Mike Created : 31/08/96 Inputs : type = the type of screen to find the name for Returns : TRUE if the type is known FALSE if the type is unknown - pString will contain the default SPOT name Purpose : Conveniently convert from a screen type to a textual name ******************************************************************************************/ BOOL TypesetInfo::GetScreenName(ScreenType type, StringBase *pString) { ERROR2IF(pString==NULL, FALSE, "NULL output string pointer passed to GetScreenName"); String_256 Str; BOOL known=TRUE; switch (type) { case SCRTYPE_SPOT2: Str.Load(_R(IDS_SCRTYPE_SPOT2)); break; case SCRTYPE_TRIPLESPOT1: Str.Load(_R(IDS_SCRTYPE_TRIPLESPOT1)); break; case SCRTYPE_TRIPLESPOT2: Str.Load(_R(IDS_SCRTYPE_TRIPLESPOT2)); break; case SCRTYPE_ELLIPTICAL: Str.Load(_R(IDS_SCRTYPE_ELLIPTICAL)); break; case SCRTYPE_LINE: Str.Load(_R(IDS_SCRTYPE_LINE)); break; case SCRTYPE_CROSSHATCH: Str.Load(_R(IDS_SCRTYPE_CROSSHATCH)); break; case SCRTYPE_MEZZOTINT: Str.Load(_R(IDS_SCRTYPE_MEZZOTINT)); break; case SCRTYPE_SQUARE: Str.Load(_R(IDS_SCRTYPE_SQUARE)); break; case SCRTYPE_DITHER: Str.Load(_R(IDS_SCRTYPE_DITHER)); break; case SCRTYPE_SPOT1: Str.Load(_R(IDS_SCRTYPE_SPOT1)); break; default: known=FALSE; Str.Load(_R(IDS_SCRTYPE_SPOT1)); break; } (*pString) = Str; return known; } /****************************************************************************************** void TypesetInfo::SetSeparations(BOOL sep) Author : Mike Created : 11/6/95 Inputs : sep = a boolean which enables or disables separation output Purpose : To turn off and on printing of separated output. if enabled, we colour-separate all output if disabled, we print normal composite output ******************************************************************************************/ void TypesetInfo::SetSeparations(BOOL sep) { MakeSeparations = sep; } /****************************************************************************************** void TypesetInfo::SetScreening(BOOL state, BOOL SetAllPlates = TRUE) Author : Mike Created : 11/6/95 Inputs : sep = a boolean which enables or disables the output of setscreen commands SetAllPlates = FALSE to simply record the new state in this info class (not recommended) TRUE to set the state in all the plates held in this class Purpose : To turn off and on printing of screened output. If screening is enabled, the colour plate screen ang, freq, function will be output to the printer If disabled, no screening info willl be sent, and thus we use the printer default settings. ******************************************************************************************/ void TypesetInfo::SetScreening(BOOL state, BOOL SetAllPlates) { UseScreening = state; if (SetAllPlates) { ColourPlate *pPlate = GetFirstPlate(); while (pPlate != NULL) { pPlate->SetActiveScreening(state); pPlate = GetNextPlate(pPlate); } } } /****************************************************************************************** void TypesetInfo::SetPrintResolution(INT32 res, BOOL SetAllPlates = TRUE); Author : Mike Created : 11/6/95 Inputs : res = a dpi resolution SetAllPlates = FALSE to simply record the new printer resolution, TRUE to reset all contained colour plates to recommended default values for the new resolution. This will set angle, freq, and function for all plates. Purpose : Use this function to set the prefered postscript device resolution. The resolution determines the set of preferred screen frequencies. ******************************************************************************************/ void TypesetInfo::SetPrintResolution(INT32 res, BOOL SetAllPlates) { PrintResolution = res; if (SetAllPlates) ResetAllPlatesToDefaultScreens(); } /****************************************************************************************** void TypesetInfo::SetDefaultScreenFrequency(double freq, BOOL SetAllPlates = TRUE) Author : Mike Created : 11/6/95 Inputs : freq = a double representing the screen frequency in lpi (possibly fractional) SetAllPlates = FALSE to simply record the new printer resolution, TRUE to reset all contained colour plates to this new screening frequency. Purpose : Use this function to set the preferred screening frequency used for plates ******************************************************************************************/ void TypesetInfo::SetDefaultScreenFrequency(double freq, BOOL SetAllPlates) { if (freq < 2.0 || freq > 10000.0) { ERROR3("Silly screen frequency"); return; } ScreenFrequency = freq; if (SetAllPlates) ResetAllPlatesToDefaultScreens(); } /****************************************************************************************** > void TypesetInfo::SetScreenFunction(ScreenType func, BOOL SetAllPlates = TRUE); Author : Mike Created : 11/6/95 Inputs : func = the screening function to set setall = TRUE, then set this screen type in all the plates in the plate list FALSE - only remember this as the default (not recommended!) Purpose : Use this function to set the preferred screening function used for plates ******************************************************************************************/ void TypesetInfo::SetScreenFunction(ScreenType func, BOOL SetAllPlates) { DefaultScreenType = func; if (SetAllPlates) { ColourPlate *pPlate = GetFirstPlate(); while (pPlate != NULL) { pPlate->SetScreenFunction(func); pPlate = GetNextPlate(pPlate); } } } /****************************************************************************************** > void TypesetInfo::ResetAllPlatesToDefaultScreens(void) Author : Jason Created : 19/8/96 Purpose : Resets all attached ColourPlates to the recommended defaults for: Screen Angle Screen Frequency Screen Function (dot shape) SeeAlso: SetPrintResolution; SetDefaultScreenFrequency; SetScreenFunction ******************************************************************************************/ void TypesetInfo::ResetAllPlatesToDefaultScreens(void) { INT32 Res = GetPrintResolution(); INT32 Freq = (INT32) floor(GetDefaultScreenFrequency()); ColourPlate *pPlate = GetFirstPlate(); while (pPlate != NULL) { pPlate->ResetScreenToDefaults(Res, Freq); pPlate->SetScreenFunction(GetScreenFunction()); pPlate = GetNextPlate(pPlate); } } /****************************************************************************************** > void TypesetInfo::EnsureAllPlatesHaveGlobalSettigns(void) Author : Jason Created : 18/9/96 Purpose : For convenience and efficiency while rendering print jobs, ColourPlates have their own copies of certain "global" flags (such as whether screening is enabled). As a consequence of this slightly untidy situation, it is possible for the colour plates to get out of step with the overall option stored in the TypesetInfo. To get around this, this function simply copies the overall option from the TypesetInfo into all its colour plates. It should be called prior to printing etc to ensure that these 'global' settings are consistent across all plates and the parent TypesettingInfo Notes: Currently copies the following states: * Screen function * Screening enabled flag ******************************************************************************************/ void TypesetInfo::EnsureAllPlatesHaveGlobalSettings(void) { ColourPlate *pPlate = GetFirstPlate(); while (pPlate != NULL) { pPlate->SetScreenFunction(GetScreenFunction()); pPlate->SetActiveScreening(AreScreening()); pPlate = GetNextPlate(pPlate); } } /****************************************************************************************** > void TypesetInfo::SetPhotoNegative(BOOL state) Author : Mike Created : 11/6/95 Inputs : state = the state of the photonegative flag Purpose : Use this function to set the photonegative local flag. ******************************************************************************************/ void TypesetInfo::SetPhotoNegative(BOOL state) { PhotoNegative = state; } /****************************************************************************************** > void TypesetInfo::SetOverprintBlack(BOOL Always) Author : Jason Created : 7/8/96 Inputs : Always - FALSE to disbale, or TRUE to enable "Always overprint black" Purpose : Sets whether "black" will be always be overprinted automatically. This works as follows: Any colour which is defined as CMYK and which has more than 95% Key component is considered "black". When AlwaysOverprintBlack is enabled, such "black" colours will be overprinted automatically. This option does not affect non-CMYK colours Notes: The TypesetInfo constructor defaults to the FALSE (disabled) state SeeAlso: RenderRegion::PrepareStrokeColour; RenderRegion::PrepareFillGeometry ******************************************************************************************/ void TypesetInfo::SetOverprintBlack(BOOL Always) { OverprintBlack = Always; } /****************************************************************************************** > BOOL TypesetInfo::CheckForExistingPlate(ColourPlateType Type, IndexedColour *SpotColour = NULL) Author : Jason Created : 25/6/96 Inputs : Type - The type of plate you are checking for SpotColour - If Type is COLOURPLATE_SPOT, then SpotColour should point to the IndexedColour defining the spot plate. It is ignored for all other types. Returns : TRUE if a matching plate is already in the list FALSE if you'll need to create and add a new plate of that type Purpose : Helper function for CreatePlateList. Determines if a plate of the given type is already available in the ColourPlate list. If Type is COLOURTYPE_SPOT, then SpotColour must also be specified. Notes: This doesn't find an exact match for the ColourPlate, but simply another plate of the same type (e.g. Another CYAN plate, or another SPOT plate which is based on the same spot colour) - all other options (monochrome, screen settings etc) are ignored in the comparison. ******************************************************************************************/ BOOL TypesetInfo::CheckForExistingPlate(ColourPlateType Type, IndexedColour *SpotColour) { ERROR3IF(Type == COLOURPLATE_SPOT && SpotColour == NULL, "Illegal NULL param"); ColourPlate *Ptr = GetFirstPlate(); while (Ptr != NULL) { if (Ptr->GetType() == Type) { // Just for safety we will make sure that the plate uses the same setting // for screen function as we do. (The plate holds a copy of this info for // convenience, and we don't really want plates using different screens) Ptr->SetScreenFunction(GetScreenFunction()); // The basic types match, but if it's a spot plate, we have to check if // it is the same actual spot plate before we have an exact match if (Type == COLOURPLATE_SPOT) { if (Ptr->GetSpotColour() == SpotColour) return(TRUE); //else // Not an exact match, so drop through to continue searching } else return(TRUE); // The types match, so return TRUE } Ptr = GetNextPlate(Ptr); } // We didn't find it, so return FALSE return(FALSE); } /****************************************************************************************** > BOOL TypesetInfo::CreatePlateList() Author : Jason (shell function by Mike) Created : 25/6/96 (11/6/95 - 95? Are you sure, Mike? ;-) Inputs : - Returns : TRUE if the plate list has been constructed correctly FALSE if there's nothing in the plate list. Purpose : This function initialises or re-initialises the document plate list. This list contains a set of ColourPlates which will be used to control the printing of the document. Each plate will produce a distinct pass in the print loop. If the ColourPlate list has already been created, this function will update it by the following means: * Ensure that the process (C,M,Y,K) plates are in the list * Remove any Spot colours from the list which have since been deleted or edited to no longer be spot colours * Add any new spot colours to the plate list Any existing plate settings for plates that are still valid will thus be retained. ******************************************************************************************/ BOOL TypesetInfo::CreatePlateList() { ColourPlate *pPlate; INT32 Res = GetPrintResolution(); INT32 Freq = (INT32) floor(GetDefaultScreenFrequency()); // --- First, make sure we've got a set of process (CMYK) plates... // Create a cyan plate to print. if (!CheckForExistingPlate(COLOURPLATE_CYAN)) { pPlate = new ColourPlate(COLOURPLATE_CYAN, TRUE, FALSE); if (pPlate) { pPlate->ResetScreenToDefaults(Res, Freq); pPlate->SetScreenFunction(GetScreenFunction()); AddPlate(pPlate); } } // Create a magenta plate to print. if (!CheckForExistingPlate(COLOURPLATE_MAGENTA)) { pPlate = new ColourPlate(COLOURPLATE_MAGENTA, TRUE, FALSE); if (pPlate) { pPlate->ResetScreenToDefaults(Res, Freq); pPlate->SetScreenFunction(GetScreenFunction()); AddPlate(pPlate); } } // Create a yellow plate to print. if (!CheckForExistingPlate(COLOURPLATE_YELLOW)) { pPlate = new ColourPlate(COLOURPLATE_YELLOW, TRUE, FALSE); if (pPlate) { pPlate->ResetScreenToDefaults(Res, Freq); pPlate->SetScreenFunction(GetScreenFunction()); AddPlate(pPlate); } } // Create a key plate to print. if (!CheckForExistingPlate(COLOURPLATE_KEY)) { pPlate = new ColourPlate(COLOURPLATE_KEY, TRUE, FALSE); if (pPlate) { pPlate->ResetScreenToDefaults(Res, Freq); pPlate->SetScreenFunction(GetScreenFunction()); AddPlate(pPlate); } } // --- Second, remove any "dead" plates (spot colours which are now deleted or // have been edited so they are no longer spot colours) pPlate = (ColourPlate *) PrintingPlates.GetHead(); ColourPlate *pNext; while (pPlate != NULL) { pNext = (ColourPlate *) PrintingPlates.GetNext(pPlate); if (pPlate->GetType() == COLOURPLATE_SPOT) { IndexedColour *pSpot = pPlate->GetSpotColour(); if (pSpot != NULL) { // If it's not a spot colour, or is deleted, then it no longer generates a plate if (pSpot->GetType() != COLOURTYPE_SPOT || pSpot->IsDeleted()) { PrintingPlates.RemoveItem(pPlate); delete pPlate; } } } pPlate = pNext; } // --- Finally, add plates for any spot colour which is not already accounted for // in the existing plate list. We use the colours from the Selected document ColourList *ColList = ColourManager::GetColourList(); ERROR3IF(ColList == NULL, "Can't find selected ColourList"); if (ColList != NULL) { IndexedColour *IxCol = (IndexedColour *) ColList->GetUndeletedHead(); while (IxCol != NULL) { if (IxCol->GetType() == COLOURTYPE_SPOT) { // We've found a spot colour. Is it already represented by a ColourPlate? if (!CheckForExistingPlate(COLOURPLATE_SPOT, IxCol)) { // No, it's not, so we'd better create a new plate for it pPlate = new ColourPlate(IxCol, TRUE, FALSE); if (pPlate) { pPlate->ResetScreenToDefaults(Res, Freq); pPlate->SetScreenFunction(GetScreenFunction()); AddPlate(pPlate); // If this colour is not used in the document, turn off printing of the plate // by default. (This isn't brilliant - it'll leave it on if the colour is used // in the UNDO, but it's better than leaving it on all the time) // NOTE: We pass in TRUE so that it will ignore one use of the colour (the // reference from the ColourPlate itself!) if (!IxCol->IsInUse(TRUE)) pPlate->SetDisabled(TRUE); } } } IxCol = (IndexedColour *) ColList->GetUndeletedNext(IxCol); } } // And now, just make sure everything is tidy EnsureAllPlatesHaveGlobalSettings(); return TRUE; } /****************************************************************************************** > void TypesetInfo::UpdatePlateList() Author : Mike Created : 31/08/96 Inputs : - Returns : - Purpose : Makes sure all the plates in the plate list have all values up-to-date. This is called on StartPrinting(). The reason it is here is that on start up, the previous settings will be loaded in and set in TypsetInfo. However, the user could print immediately without bringing up any extra print option tabs. The list of plates is created needs to be updated with the loaded settings. ******************************************************************************************/ void TypesetInfo::UpdatePlateList() { // Make sure all plate screening values are up-to-date SetScreening(UseScreening,TRUE); // Make sure screen plate / lpi / freq / angles are all correct ResetAllPlatesToDefaultScreens(); } /****************************************************************************************** > ColourPlate *TypesetInfo::CreateColourPlate() Author : Jason Created : 16/8/96 Inputs : - Returns : NULL (failed) or a new colour plate Purpose : Creates a new colour plate The plate defaults to the same as for the ColourPlate() default constructor (i.e. COLOURPLATE_NONE), but things like the screen function will be set up by copying them from this TypesetInfo object. This function is intended only for use by the native file import code, which creates colour plates if any were saved in the file. However, each plate takes many settings from its parent TypesetInfo (they're only stored in the plate for easy access/efficiency when rendering) Notes: See Also CheckForExistingPlate() which also sets the plate screen functions to make sure they tow the party line... ******************************************************************************************/ ColourPlate *TypesetInfo::CreateColourPlate() { ColourPlate *pNewPlate = new ColourPlate(COLOURPLATE_NONE, TRUE, FALSE); // The only special info we currently need to set is the screen function... if (pNewPlate != NULL) pNewPlate->SetScreenFunction(GetScreenFunction()); return(pNewPlate); } /****************************************************************************************** > void TypesetInfo::DestroyPlateList() Author : Mike Created : 11/6/95 Inputs : - Returns : - Purpose : This function simply empties the entire plate list of its contents, deleting each record as it goes. It is a seriously non-constant function. ******************************************************************************************/ void TypesetInfo::DestroyPlateList() { ColourPlate *pPlate; while ((pPlate=(ColourPlate*)PrintingPlates.RemoveTail())) // Assignment delete pPlate; // We have no plates, so it's best to vape our current pointers CurrentPlate = NULL; CurrentPrintPlate = NULL; } /****************************************************************************************** > void TypesetInfo::AddPlate(ColourPlate* pPlate) Author : Mike Created : 11/6/95 Inputs : pPlate = a pointer to a colour plate Returns : - Purpose : Use this function to add a colour plate to the colour plate list. Note, the calling function no longer has ownership of this object. The object will be deleted automatically from the list whenever the plate list class is destroyed. ******************************************************************************************/ void TypesetInfo::AddPlate(ColourPlate* pPlate) { ERROR3IF(pPlate==NULL, "AddPlate given a NULL plate pointer!"); PrintingPlates.AddTail(pPlate); } /****************************************************************************************** > void TypesetInfo::SetCurrentPlate(ColourPlate* pPlate) Author : Mike Created : 11/6/95 Inputs : pPlate = a pointer to a colour plate Returns : - Purpose : Use this function to set the current colour plate. This current plate object is usually shown as the highlighted plate in the printing dialogue plate display list. ******************************************************************************************/ void TypesetInfo::SetCurrentPlate(ColourPlate* pPlate) { ERROR3IF(pPlate==NULL, "SetCurrentPlate given a NULL plate pointer!"); CurrentPlate = pPlate; } /****************************************************************************************** > ColourPlate* TypesetInfo::GetCurrentPlate() const Author : Mike Created : 11/6/95 Inputs : - Returns : a pointer to the current colour plate Purpose : Use this function to retrieve a pointer to the current plate. The current plate variable simply keeps track of the selected plate in the printing UI. This plate is the one which will receive all edits. ******************************************************************************************/ ColourPlate* TypesetInfo::GetCurrentPlate() const { return CurrentPlate; } /****************************************************************************************** > DWORD TypesetInfo::GetNumPlates() const Author : Mike Created : 11/6/95 Inputs : - Returns : a dword, the number of plates in the list Purpose : Returns the number of plates in the print class plate list ******************************************************************************************/ DWORD TypesetInfo::GetNumPlates() const { return PrintingPlates.GetCount(); } /****************************************************************************************** > void TypesetInfo::InitPlatesForPrinting() Author : Mike Created : 11/6/95 Inputs : - Returns : - Purpose : Set up the plate printing service. This should be called before any attempt to access the functions GetNextPrintPlate(), NumPrintPlatesRemaining etc ******************************************************************************************/ void TypesetInfo::InitPlatesForPrinting() { // We don't need to do anything if we're not separating, but as we // do nothing but set a plate, we don't need extra check code here // Set our internal current plate CurrPrintPlateNum=1; NumPrintPlates=1; CurrentPrintPlate=NULL; PrintPlatesToGo=1; if (AreSeparating()) { NumPrintPlates = GetNumPrintPlates(); PrintPlatesToGo = NumPrintPlates; } } /****************************************************************************************** > ColourPlate* TypesetInfo::GetFirstPrintPlate() Author : Mike Created : 11/6/95 Inputs : - Returns : A pointer to the first print plate (NULL if no more) Purpose : Return the first plate through which the document will be printed. The class variables CurrentPrintPlate and CurrPrintPlateNum will be set. ******************************************************************************************/ ColourPlate* TypesetInfo::GetFirstPrintPlate() { // Retrieve the first plate from the list ColourPlate *pPlate = GetFirstPlate(); return GetPrintPlate(0,pPlate); } /****************************************************************************************** > ColourPlate* TypesetInfo::GetNextPrintPlate() Author : Mike Created : 11/6/95 Inputs : - Returns : A pointer to the next print plate (NULL if no more) Purpose : Return the next plate through which the document will be printed. The class variables CurrentPrintPlate and CurrPrintPlateNum will be used to determin the next plate ******************************************************************************************/ ColourPlate* TypesetInfo::GetNextPrintPlate() { ColourPlate *pPlate; if (CurrentPrintPlate==NULL) { // Retrieve the first plate from the list pPlate = GetFirstPlate(); return GetPrintPlate(0,pPlate); } // otherwise retrieve the next plate pPlate = GetNextPlate(CurrentPrintPlate); return GetPrintPlate(CurrPrintPlateNum,pPlate); } /****************************************************************************************** ColourPlate* TypesetInfo::GetPrintPlate(DWORD num, ColourPlate* pPlate) Author : Mike Created : 11/6/95 Inputs : num = the number of the plate pPlate = a pointer to the plate Returns : A pointer to a print plate (NULL if none) Purpose : This function is an internal helper function to GetFirstPrintPlate() and GetNextPrintPlate() ******************************************************************************************/ ColourPlate* TypesetInfo::GetPrintPlate(DWORD pnum, ColourPlate* pPlate) { while (pPlate!=NULL) { pnum++; // if this plate is not disabled then return it if (!pPlate->IsDisabled()) { CurrPrintPlateNum=pnum; PrintPlatesToGo--; return (CurrentPrintPlate=pPlate); } pPlate=GetNextPlate(pPlate); } return NULL; } /****************************************************************************************** > DWORD TypesetInfo::GetNumPrintPlates() const Author : Mike Created : 11/6/95 Inputs : - Returns : A DWORD, the number of plates this document can theoretically be separated to. This will usually be 4 (C,M,Y and K) plus any spot colour plates Purpose : Find out how many print plates are stored in the plate list. ******************************************************************************************/ DWORD TypesetInfo::GetNumPrintPlates() const { ColourPlate* pPlate; DWORD nPlates=0; pPlate = GetFirstPlate(); while (pPlate!=NULL) { if (!pPlate->IsDisabled()) nPlates++; pPlate=GetNextPlate(pPlate); } return nPlates; } /****************************************************************************************** > ColourPlate* TypesetInfo::GetCurrentPlate() const Author : Jason Created : 5/8/96 Inputs : - Returns : a pointer to the currently PRINTING colour plate Purpose : Use this function to retrieve a pointer to the currently printing plate. ******************************************************************************************/ ColourPlate* TypesetInfo::GetCurrentPrintPlate() const { return CurrentPrintPlate; } /****************************************************************************************** > void TypesetInfo::NumPrintPlatesRemaining() Author : Mike Created : 11/6/95 Inputs : - Returns : The number of plate which remain to be printed Purpose : Calculate and return the number of plates remaining for this piece of paper ******************************************************************************************/ INT32 TypesetInfo::NumPrintPlatesRemaining() const { // Calculate the number of plates remaining print return ( PrintPlatesToGo ); } /****************************************************************************************** > void TypesetInfo::SetNextCompositePlate() Author : Mike Created : 11/6/95 Inputs : - Returns : - Purpose : Called from PrintControl::SetNextPlate(). This function simply allows composite printing to pass around the plate loop once without actually setting any plates. This function will set the internal typeset plate variables so that MorePlates() will return FALSE the next time it is called. ******************************************************************************************/ void TypesetInfo::SetNextCompositePlate() { // Do absolutely nothing if we are in separation mode if (AreSeparating()) return; // Set out internal variables so a call to MorePlates() // will terminate the print loop CurrentPrintPlate=NULL; PrintPlatesToGo=0; }