using System;
using System.Collections.Generic;
using System.Text;
using VEPROMS.CSLA.Library;
using Volian.Base.Library;
using iTextSharp.text.pdf;
using Volian.Svg.Library;
namespace Volian.Print.Library
{
public partial class vlnParagraph
{
///
/// This variable is used to match 16 bit pagination
///
private bool _Match16BitPagination = false;
///
/// Dtermines if the current step is preceded by a Page Break
///
///
///
///
///
/// 0 - No page break
/// 1 - Break on High Level Step
/// 2 - Break within a Step
/// 3 - Break on High Level Step (SevenLinesPerInch)
///
private int Paginate(float yLocation, float yTopMargin, float yBottomMargin)
{
float yPageSize = yTopMargin - yBottomMargin;
// TODO: This does not account for a long step as the last step that would exceed more than one page and
// that has an end message that needs to be accounted for in determining pagination. To do that the last
// child should be the only paragraph that accounts for the End message.
//
// If last step & there should be an end message, pagination tests need to account for the 3 lines the end
// message uses. The 3 is for a line above, the end message line & the line below (in case there is a border/box line).
// The 3 was changed to 2 for the end line & the line below. The blank line below the step gives the blank
// line above the end message, thus 2 not 3. This change was made on July 20, 2011 by RHM & KBR. The
// procedure in questions was VEWCNEMG\EMGAPP.PRC, ES-01, Step 8.
bool ManualPageBreak = false;
float yEndMsg = !MyItemInfo.IsSection && MyItemInfo.MyHLS.NextItem == null && (MyItemInfo.MyDocStyle.End.Message ?? "") != "" ? 2 * SixLinesPerInch : 0;
float yWithinMargins = CalculateYLocation(yLocation, yTopMargin) - yBottomMargin; // -SixLinesPerInch;
// if step is breaking over a number of pages, determine if the current step is the
// location of a pagebreak.
if (MyItemInfo.ItemID == 54 || MyItemInfo.ItemID == 54) Console.WriteLine("here");
if (MyPageHelper.ParaBreaks.Count > 0)
{
if (this == MyPageHelper.ParaBreaks[0] || this.YTopMost > MyPageHelper.ParaBreaks[0].YTopMost)
{
MyPageHelper.ParaBreaks.RemoveAt(0);
//Console.WriteLine("'PageBreak',6,'Yes','Page Break within Step',{0},{1},{2},{3}, {4},'{5}'", MyItemInfo.ItemID, YSize, 0, 0, 0, MyItemInfo.ShortPath);
//Console.WriteLine("Prev = {0}", MyItemInfo.MyPrevious==null ? "''" : MyItemInfo.DBSequence);
ShowPageBreak(1, "Page Break within Step", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
return 2; // break on this item within a step
}
return 0; // this is not an item with a break
}
float mySize = YSize * MyPageHelper.YMultiplier;
vlnParagraph firstChild = ChildrenBelow.Count > 0 ? ChildrenBelow[0] : null;
float ySizeIncludingFirst = firstChild == null ? YSize : firstChild.YSize + (firstChild.YTopMost - YTopMost);
bool KeepStepsOnPage = MyItemInfo.ActiveFormat.MyStepSectionLayoutData.KeepStepsOnPage;
if (MyItemInfo.IsStepSection)
{
if (yLocation < yTopMargin) // continuous section
{
if (ChildrenBelow == null || ChildrenBelow.Count == 0)
{
// see if there is an end message. This is stored in the helper - if there is,
// we need to be sure that there is room for it.
if (MyPageHelper.BottomMessage != null)
{
if (mySize + yEndMsg <= yWithinMargins) return 1;
}
return 0;
}
// This is a continuous section. There may be cases where the user put a manual page
// break on the first step (child) in the section. if so, break on the section. The
// flag SectionPageBreak is set to true to flag that a pagebreak should not be done
// on that first step.
StepConfig sc = firstChild.MyItemInfo.MyConfig as StepConfig;
ManualPageBreak = MyPageHelper.OriginalPageBreak ? (sc == null ? false : sc.Step_ManualPagebreak) :
sc == null ? false : sc.Step_NewManualPagebreak;
if (ManualPageBreak)
{
SectionPageBreak = true;
ShowPageBreak(2, "Section Page Break", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
return 1;
}
// can the title and the first step fit?
// add the first child's size + (the section title's size)
//if (ySizeIncludingFirst > (yLocation - yBottomMargin - SixLinesPerInch)) return 1;
//if (ySizeIncludingFirst > (yLocation - yBottomMargin) && ySizeIncludingFirst < yPageSize)
vlnParagraph firstStepChild = firstChild;
//while (firstStepChild.MyItemInfo.IsSection && firstStepChild.ChildrenBelow.Count > 0) firstStepChild = firstStepChild.ChildrenBelow[0];
while (firstStepChild.ChildrenBelow.Count > 0 && (firstStepChild.MyItemInfo.IsSection || firstStepChild.MyItemInfo.IsHigh)) firstStepChild = firstStepChild.ChildrenBelow[0];
float ySizeIncludingFirstStep = firstStepChild.YSize + (firstStepChild.YTopMost - YTopMost);
bool isFirstSection = MyItemInfo.MyPrevious == null;
bool nearTheTop = yWithinMargins > (yPageSize - 5 * SixLinesPerInch);
bool firstSubstepExceedsSpaceAvailable = ySizeIncludingFirstStep > yWithinMargins;
if (KeepStepsOnPage && firstSubstepExceedsSpaceAvailable && !isFirstSection)
KeepStepsOnPage = false;
if (!KeepStepsOnPage && ySizeIncludingFirst > (yLocation - yBottomMargin))
{
ShowPageBreak(4, "Page Break Before Continuous Step Section", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
return 1;
}
}
return 0; // Don't Paginate (page break) on a Step Section if it's first thing on page
}
if (!MyItemInfo.IsHigh) return 0; // Don't Paginate on a Substep level
StepConfig sc1 = MyItemInfo.MyConfig as StepConfig;
ManualPageBreak = MyPageHelper.OriginalPageBreak ? (sc1 == null ? false : sc1.Step_ManualPagebreak) :
sc1 == null ? false : sc1.Step_NewManualPagebreak;
if (MyItemInfo.FirstSibling == MyItemInfo && ManualPageBreak)
{
// if parent/section used this pagebreak, skip it.
if (MyParent.SectionPageBreak)
{
ManualPageBreak = false;
MyParent.SectionPageBreak = false;
}
}
if (_Match16BitPagination) mySize = YSize;
float ySize7LPI = YSize; // +SixLinesPerInch;
if (_Match16BitPagination) ySize7LPI += SixLinesPerInch;
string firstStep = "No";
if (MyItemInfo.IsHigh && MyItemInfo.MyPrevious == null)
firstStep = "Yes";
//if (!ManualPageBreak && mySize + yEndMsg <= yWithinMargins) // Don't Paginate if there is enough room, will fit on page
// Pagination Fix - Break1LineShort1
float yExtra = (yWithinMargins == yPageSize ? 0 : SixLinesPerInch - MyItemInfo.MyDocStyle.Layout.FooterLength) ?? 0;
float yExtra2 = (SixLinesPerInch - MyItemInfo.MyDocStyle.Layout.FooterLength) ?? 0;
if (KeepStepsOnPage && ySizeIncludingFirst > yWithinMargins)
KeepStepsOnPage = false;
if (!ManualPageBreak && mySize + yEndMsg <= yWithinMargins + yExtra) // Don't Paginate if there is enough room, will fit on page
//if (!ManualPageBreak && mySize + yEndMsg <= yWithinMargins + SixLinesPerInch) // Don't Paginate if there is enough room, will fit on page
{
//Console.WriteLine("'PageBreak',1,'No','HLS will fit on page',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
ShowPageBreak(-1, "HLS will fit on page", firstStep, YSize, yPageSize, yWithinMargins,ManualPageBreak);
return 0;
}
// !MyItemInfo.IsHigh - if (MyItemInfo.IsRNOPart && MyParent.XOffset < XOffset) return 0; // Don't paginate on an RNO to the right
// YSize includes a blank line after the step which we don't want to include in the page break test, thus the
// YSize - SixLinesPerInch:
if (!KeepStepsOnPage && YSize - SixLinesPerInch + yEndMsg <= yPageSize) // if the entire step can fit on one page, do a page break
{
// Don't want extra line before step
//Console.WriteLine("'PageBreak',2,'Yes','HLS will fit on 1 Page',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
ShowPageBreak(5, "HLS will fit on 1 Page at 6 LPI", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
return 1;
}
// TODO - yEndMsg - compressed size?
// ySize7LPI includes a blank line after the step which we don't want to include in the page break test.
else if (!KeepStepsOnPage && MyItemInfo.ActiveFormat.MyStepSectionLayoutData.CompressSteps && (ySize7LPI - SixLinesPerInch) < (yPageSize * SixLinesPerInch / _SevenLinesPerInch))
{
//Console.WriteLine("'PageBreak',3,'Yes','HLS will fit on 1 Page at 7 LPI',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
ShowPageBreak(7, "HLS will fit on 1 Page at 7 LPI", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
//Console.WriteLine("'7LPI',{0},{1}", MyItemInfo.DBSequence, YSize);
return 3; // High Level Step can fit at SevenLinesPerInch
}
else // The entire step cannot fit on a blank page.
{
// if there is more than half a page left, then start to print on the current page
float myFirstPieceSize = GetFirstPieceSize(); //Case 0
if (_Match16BitPagination) myFirstPieceSize += 2 * SixLinesPerInch;
// TODO: Put this line back to case 0, i.e. previous line. This fixes a 16-bit vs 32-bit pagination diff in EO30 Step 20.
//float myFirstPieceSize = GetFirstPieceSize() + 2 * SixLinesPerInch; //Case 10 - this is to match 16bit
if (!ManualPageBreak && ((MyItemInfo.ActiveFormat.MyStepSectionLayoutData.SpecialPageBreakFlag && yWithinMargins > yPageSize / 2 &&
myFirstPieceSize < yWithinMargins) || KeepStepsOnPage))
{
//Console.WriteLine("'PageBreak',4,'No','HLS will have to split anyway',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
if(firstStep == "Yes")
ShowPageBreak(8, "First HLS has to split on current page", firstStep, YSize, yPageSize, yWithinMargins, ManualPageBreak);
else
ShowPageBreak(6, "HLS will have to split on current page", "Special", YSize, yPageSize, yWithinMargins, ManualPageBreak);
//BuildPageBreakList(yWithinMargins+SixLinesPerInch,yPageSize-2*SixLinesPerInch); // Determine items where page break(s) occur
//BuildPageBreakList(yWithinMargins + SixLinesPerInch, yPageSize); // Case 5 - Determine items where page break(s) occur
// Pagination Fix Break1LineShort3a
BuildPageBreakList(yWithinMargins + SixLinesPerInch, yPageSize + yExtra2,KeepStepsOnPage); // Case 5 - Determine items where page break(s) occur
return 0; // Stay on this page
}
// Less than half a page left, start printing on a new page.
//Console.WriteLine("'PageBreak',5,'Yes','HLS will have to split',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
if (firstStep == "Yes")
ShowPageBreak(9, "First HLS will have to split on new page", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
else
ShowPageBreak(3, "HLS will have to split on new page", "Yes", YSize, yPageSize, yWithinMargins, ManualPageBreak);
// Determine items where page break(s) occur
//BuildPageBreakList(yPageSize, yPageSize - 2 * SixLinesPerInch); // Case Base
//BuildPageBreakList(yPageSize, yPageSize); // Case 1 :Works for ES05 Step 15 SubStep 7
// Pagination Fix Break1LineShort2
//BuildPageBreakList(yPageSize + yExtra, yPageSize); // Case 1 :Works for ES05 Step 15 SubStep 7
// Pagination Fix Break1LineShort4
BuildPageBreakList(yPageSize + yExtra, yPageSize + yExtra2,KeepStepsOnPage); // Case 1 :Works for ES05 Step 15 SubStep 7
return 1; // Paginate on High Level Steps
}
//if (yWithinMargins > yPageSize / 2)
//{
// Console.WriteLine("'PageBreak',4,'No','Not Half way down the page',{0},{1},{2}, {3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
// return 0; // More than half way down the page
//}
//if (ChildrenBelow.Count > 0 && ChildrenBelow[0].YSize < yWithinMargins)
// return 0;
//Console.WriteLine("'PageBreak',5,'Yes','At least half the page is filled',{0},{1},{2},{3}, {4},'{5}'", MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize), MyItemInfo.ShortPath);
//return 2;
throw new Exception("PageBreak Logic Missing, vlnParagraph.cs");
}
private void ForcePagination(PdfContentByte cb, ref float yPageStart, float yTopMargin, float yBottomMargin, ref float yLocation, ref float retval)
{
cb.PdfDocument.NewPage(); // pagination issue
DebugText.WriteLine("*****PaginateError");
yPageStart = yTopMargin + YVeryTop;
yLocation = yPageStart - YOffset;
//MyItemInfo.ItemID, YSize, yPageSize, yLocation
DebugPagination.WriteLine("-1,'Yes','Forced Pagination',{0},{1},,{3},{4}", MyItemInfo.ItemID, YSize, 0, yLocation, MyItemInfo.DBSequence);
retval = Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, DebugInfo, yBottomMargin);
}
private void ShowPageBreak(int instance, string message, string breakOrNot, float YSize, float yPageSize, float yWithinMargins, bool manualPageBreak)
{
if (breakOrNot != "No")
{
// DebugPagination.WriteLine("{0}", MyItemInfo.DBSequence); //,instance);
DebugPagination.WriteLine("{0},'{1}',{2},'{3}','{4}',{5},{6},{7},{8},{9}",
MyPageHelper.MyPdfContentByte.PdfWriter.CurrentPageNumber - (breakOrNot == "Yes" ? 0 : 1),
MyItemInfo.ShortPath, instance,
(manualPageBreak ? "Manual " : "") + message, breakOrNot,
MyItemInfo.ItemID, YSize, yPageSize, yWithinMargins, (int)(100 * yWithinMargins / yPageSize));
}
// Console.WriteLine("{0},{1}", MyItemInfo.DBSequence, IsFirstSubStep(MyItemInfo)); //,instance);
}
private void BuildPageBreakList(float ySpaceOnCurPage, float yPageSize, bool KeepStepsOnPage)
{
ParagraphLocations myLocations = new ParagraphLocations();
BuildLocationList(YTopMost, myLocations);
StepLevelList myList = myLocations.BuildStepLevelList(KeepStepsOnPage);
// Find Break Locations in the list based upon StepLevel and yLocation
float yTop = 0;
float yLowerLimit = (yPageSize - 2 * SixLinesPerInch) / 2;
float yStart = Math.Max(0, (yPageSize - 2 * SixLinesPerInch) - ySpaceOnCurPage);
//Console.WriteLine("'yStart',{0},{1}", MyItemInfo.DBSequence, yStart);
// The following three lines make page breaking match 16-bit:
if (_Match16BitPagination)
{
yLowerLimit = yStart - SixLinesPerInch + ySpaceOnCurPage / 2;
if ((yStart + MyItemInfo.MyDocStyle.Layout.TopMargin + 2 * SixLinesPerInch) > ((MyItemInfo.MyDocStyle.Layout.TopMargin + yPageSize - 2 * SixLinesPerInch) / 2))
yLowerLimit = yStart + 2 * SixLinesPerInch;
}
// Make sure that the FirstPiece (Caution Note HLS and First Substeps) fit
float myFirstPieceSize = GetFirstPieceSize(); //Case 0
if (myFirstPieceSize < ySpaceOnCurPage) yLowerLimit = Math.Max(myFirstPieceSize + yStart, yLowerLimit);
//while ((YSize - yTop) >= ySpaceOnCurPage)
// Pagination Fix Break1LineShort3b
while ((YSize - yTop) > ySpaceOnCurPage)
{
vlnParagraph paraBreak = FindPageBreak(yStart, ySpaceOnCurPage, yLowerLimit, myList);
if (paraBreak == null) break;
// yTopNew is y Location of this page break. YTopMost is top of HLS, including any Cautions/Notes/Boxes/etc
float yTopNew = paraBreak.YVeryTop - YTopMost;
RemoveProcessedParagraphs(myList, yTopNew - yTop);
yTop = yTopNew;
MyPageHelper.ParaBreaks.Add(paraBreak);
ySpaceOnCurPage = yPageSize - 2 * SixLinesPerInch; // Allow for continue message and blank line.
//ySpaceOnCurPage = yPageSize; // Allow for continue message and blank line.
//DocStyle docstyle = MyItemInfo.MyDocStyle;
//string myMsg = docstyle.Continue.Bottom.Message;
//if ((myMsg ?? "") != "") ySpaceOnCurPage -= 2 * SixLinesPerInch; // Allow for continue message and blank line.
yLowerLimit = ySpaceOnCurPage / 2;
if (_Match16BitPagination) yLowerLimit -= 1.5F * SixLinesPerInch; // 276 for HLP
yStart = 0;
}
}
///
/// Finds the highest StepLevel (lowest StepLevel number, 0 = HLS, 1 = first substep) that
/// fills the page sufficiently (more than half-full)
///
///
///
///
///
private static vlnParagraph FindPageBreak(float yStart, float yUpperLimit, float yLowerLimit, StepLevelList myList)
{
foreach (int stepLevel in myList.Keys) // loop thru StepLevels, starting with lowest.
{
foreach (float yLocation in myList[stepLevel].Keys) // loop thru yLocation
{
// The top of this step will fit onto page (-yLocation < yWithinMargins)
if (-yLocation <= yUpperLimit) // Fix for OFN-RJ-23
//if (-yLocation < yUpperLimit) // Before
//if (-yLocation < yWithinMargins && myList[stepLevel][yLocation].MyItemInfo.MyPrevious != null)
{
//ItemInfo prev = myList[stepLevel][yLocation].MyItemInfo.MyPrevious;
//if (myList[stepLevel][yLocation].MyItemInfo.ItemID == 5609) Console.WriteLine("aer");
//if (myList[stepLevel][yLocation].MyItemInfo.ItemID == 4312) Console.WriteLine("rno");
// The top of this step is more than 1/2 way down the page
if ((-yLocation + yStart) >= yLowerLimit)
{
return myList[stepLevel][yLocation];
}
// if is a caution or note & parent is a substep and entire substep doesn't fit, break.
if ((myList[stepLevel][yLocation].MyItemInfo.IsNote || myList[stepLevel][yLocation].MyItemInfo.IsCaution) &&
!myList[stepLevel][yLocation].MyParent.MyItemInfo.IsHigh &&
myList[stepLevel][yLocation].MyParent.YSize > (yUpperLimit + yLocation))
{
return myList[stepLevel][yLocation];
}
}
}
}
return null;
}
//private void WalkStepLevel(float yTopMost)
//{
// foreach (vlnParagraph child in ChildrenAbove)
// child.WalkStepLevel(yTopMost);
// foreach (vlnParagraph child in ChildrenLeft)
// child.WalkStepLevel(yTopMost);
// ShowStepLevel(yTopMost);
// foreach (vlnParagraph child in ChildrenRight)
// child.WalkStepLevel(yTopMost);
// foreach (vlnParagraph child in ChildrenBelow)
// child.WalkStepLevel(yTopMost);
//}
//private void ShowStepLevel(float yTopMost)
//{
// ItemInfo item = MyItemInfo;
// ItemInfo parent = item.ActiveParent as ItemInfo;
// //if (para.MyItemInfo.ItemID == 205)
// // Console.Write("");
// DebugPagination.WriteLine("'StepLevel',{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}", YVeryTop - yTopMost, YSize, YBottomMost - yTopMost, item.ItemID, item.DBSequence, item.StepLevel, item.MyContent.Type % 10000,
// parent.MyContent.Type % 10000, item.HasCautionOrNote ? 1 : 0, parent.Cautions == null ? 0 : 1);
//}
}
public partial class VlnSvgPageHelper : SvgPageHelper
{
private bool _OriginalPageBreak; // use 16bit page breaks.
public bool OriginalPageBreak
{
get { return _OriginalPageBreak; }
set { _OriginalPageBreak = value; }
}
// This handles Page Breaks within a Step
private List _ParaBreaks = new List();
public List ParaBreaks
{
get { return _ParaBreaks; }
set { _ParaBreaks = value; }
}
}
}