diff --git a/PROMS/Volian.Print.Library/vlnBox.cs b/PROMS/Volian.Print.Library/vlnBox.cs index 38e366e4..34ad7e00 100644 --- a/PROMS/Volian.Print.Library/vlnBox.cs +++ b/PROMS/Volian.Print.Library/vlnBox.cs @@ -170,13 +170,16 @@ namespace Volian.Print.Library cb.LineTo(right, top); break; case BoxAsteriskWithSides1: - case BoxAsteriskWithSides2: case BoxAsteriskWithSides3: case BoxAsteriskWithSides4: case BoxAsteriskWithSides5: DrawAsteriskTopBottom(cb, yPageStart, yTopMargin, yBottomMargin, ref top, ref bottom, left, MyBox.Font); DrawAsteriskSide(cb, yPageStart, yTopMargin, yBottomMargin, top, bottom, left, right, MyBox.Font); break; + case BoxAsteriskWithSides2: // special processing for IP3's box + DrawAsteriskTopBottomHLS(cb, yPageStart, yTopMargin, yBottomMargin, ref top, ref bottom, left, MyBox.Font); + DrawAsteriskSideHLS(cb, yPageStart, yTopMargin, yBottomMargin, top, bottom, left, right, MyBox.Font); + break; default: // For other than thick, thin and double. if (!_UnimplementedBoxStyles.Contains(MyBox.BoxStyle)) @@ -228,7 +231,7 @@ namespace Volian.Print.Library bottom = top - (Height * MyPageHelper.YMultiplier); // create a new font without any styles such as underline. - E_Style es = ((vef.Style & E_Style.Bold) == E_Style.Bold) ? E_Style.Bold : E_Style.None; + E_Style es = ((vef.Style & E_Style.Bold) == E_Style.Bold) ? E_Style.Bold : E_Style.None; // if the box has a font, use it - otherwise use this item info's font VE_Font vf = null; bool UseBoxFont = false; @@ -252,7 +255,7 @@ namespace Volian.Print.Library // Do the top line first: StringBuilder sb = new StringBuilder(); sb.Append(MyBox.BXULC); - float size = GetTextWidth(vf,MyBox.BXULC); //(float)(MyBox.BXULC.Length * (72 / vf.CPI)); + float size = GetTextWidth(vf, MyBox.BXULC); //(float)(MyBox.BXULC.Length * (72 / vf.CPI)); string bxstr = null; if (!ContainsPageBreak) // Only do top line if there is no page break. { @@ -320,7 +323,6 @@ namespace Volian.Print.Library //float w = iFont.BaseFont.GetWidthPointKerned(Text.Replace("\u25CF","@"), (float)vefont.Size); return w; } - private void DrawAsteriskSide(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin, float top, float bottom, float left, float right, VE_Font vef) { // set the top & bottom of sides. If there is a page break in the middle of box, adjust these. @@ -333,13 +335,14 @@ namespace Volian.Print.Library else { // to calculate the bottom, don't adjust the top yet. - top = CalculateYOffset(yPageStart, yTopMargin); - bottom = top - (Height * MyPageHelper.YMultiplier); + top = CalculateYOffset(yPageStart, yTopMargin); + bottom = top - (Height * MyPageHelper.YMultiplier); top = yTopMargin; // reset top to top margin since there was a page break. } // Check that the bottom is within the bottom margin, if this step spans more than one page, // stop the side asterisks at the bottom margin. (pagination puts inserts a page break here) + if (bottom < yBottomMargin) bottom = yBottomMargin; float height = (SixLinesPerInch * MyPageHelper.YMultiplier) + 4; // just add a little on so that height is a little bigger than character @@ -371,7 +374,7 @@ namespace Volian.Print.Library { Rtf2Pdf.TextAt(cb, IParagraph, left, vertDiff, width, height, "", yBottomMargin); vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier); - } + } // right side: vertDiff = top - (SixLinesPerInch * MyPageHelper.YMultiplier); @@ -383,6 +386,7 @@ namespace Volian.Print.Library vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier); } } + private string ShowBoxStyle(string str) { StringBuilder sb = new StringBuilder(); @@ -406,5 +410,148 @@ namespace Volian.Print.Library } return sb.ToString(); } + private void DrawAsteriskTopBottomHLS(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin, ref float top, ref float bottom, float left, VE_Font vef) + { + // this box is not drawn, it is a series of asterisks drawn above and below text. + top = CalculateYOffset(yPageStart, yTopMargin); + if (MyPageHelper.YMultiplier != 1) top += 2; + bottom = (yPageStart - (MyParent.YBottomForBox > 0 ? MyParent.YBottomForBox : MyParent.YBottomMost)) * MyPageHelper.YMultiplier; + //_MyLog.WarnFormat("\"ATB\"\t\"{0}\"\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}", MyParent, yPageStart, top, bottom, MyPageHelper.YMultiplier, MyPageHelper.CurrentPageNumber, MyParent.YBottomMost, MyParent.YBottomForBox); + + // create a new font without any styles such as underline. + E_Style es = ((vef.Style & E_Style.Bold) == E_Style.Bold) ? E_Style.Bold : E_Style.None; + // if the box has a font, use it - otherwise use this item info's font + VE_Font vf = null; + bool UseBoxFont = false; + try + { + UseBoxFont = MyParent.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox; + } + catch // done this way in case one of the format properties is null in the previous statement, UseBoxFont will be false. + { + } + if (UseBoxFont) + vf = new VE_Font(vef.Family, (int)vef.Size, es, (float)MyParent.MyItemInfo.FormatStepData.Font.CPI); + else + vf = new VE_Font(MyParent.MyItemInfo.FormatStepData.Font.Family, (int)MyParent.MyItemInfo.FormatStepData.Font.Size, es, (float)MyParent.MyItemInfo.FormatStepData.Font.CPI); + + // To find the length of the line, account for the length of the upper right corner also (BXURC) + int urcLen = MyBox.BXHorz[MyBox.BXHorz.Length - 1] == ' ' && MyBox.BXURC[0] == ' ' ? 1 : MyBox.BXURC.Length; + float endHorz = (float)MyBox.End - (float)MyBox.Start - (float)(urcLen * (72 / vf.CPI)); + + float bxHorzTextWidth = GetTextWidth(vf, MyBox.BXHorz); // get the width of the BXHorz string + // Do the top line first: + StringBuilder sb = new StringBuilder(); + sb.Append(MyBox.BXULC); + float size = GetTextWidth(vf, MyBox.BXULC); //(float)(MyBox.BXULC.Length * (72 / vf.CPI)); + string bxstr = null; + if (!ContainsPageBreak) // Only do top line if there is no page break. + { + while (size < endHorz) + { + sb.Append(MyBox.BXHorz); + size = size + bxHorzTextWidth; //(float)(MyBox.BXHorz.Length * (72 / vf.CPI)); + } + // Tack on the right upper corner. For some formats, the upper right corner in the + // had the first character as a space, this would put two spaces in a row at the + // end of the string, so remove the space before tacking on the upper right corner: + bxstr = sb.ToString(); + if (bxstr[bxstr.Length - 1] == ' ' && MyBox.BXURC[0] == ' ') bxstr = bxstr.TrimEnd(); + bxstr = bxstr + MyBox.BXURC; + size = size + GetTextWidth(vf, MyBox.BXURC);//(float)((MyBox.BXURC.Length) * (72 / vf.CPI)); + Rtf = GetRtf(bxstr, vf); + IParagraph = null; // set to null so that next access of IParagraph sets the Rtf. + Rtf2Pdf.TextAt(cb, IParagraph, left, top, size + 10, 100, "", yBottomMargin); + } + + // Handle the bottom line now: + if (bottom < yBottomMargin) return; // Box goes off page, i.e. page break, don't do bottom + + sb.Remove(0, sb.Length); + sb.Append(MyBox.BXLLC); + size = GetTextWidth(vf, MyBox.BXLLC); //(float)(MyBox.BXLLC.Length * (72 / vf.CPI)); + while (size < endHorz) + { + sb.Append(MyBox.BXHorz); + size = size + bxHorzTextWidth;//(float)(MyBox.BXHorz.Length * (72 / vf.CPI)); + } + bxstr = sb.ToString().TrimEnd() + MyBox.BXLRC; + size = size + GetTextWidth(vf, MyBox.BXLRC); //(float)((MyBox.BXLRC.Length) * (72 / vf.CPI)); + Rtf = GetRtf(bxstr, vf); + IParagraph = null; // set to null so that next access of IParagraph sets the Rtf. + Rtf2Pdf.TextAt(cb, IParagraph, left, bottom, size + 10, 100, "", yBottomMargin); + } + private void DrawAsteriskSideHLS(PdfContentByte cb, float yPageStart, float yTopMargin, float yBottomMargin, float top, float bottom, float left, float right, VE_Font vef) + { + // set the top & bottom of sides. If there is a page break in the middle of box, adjust these. + // The vlnBox property, ContainsPageBreak, flags that a break occurred. + if (!ContainsPageBreak) + { + top = CalculateYOffset(yPageStart, yTopMargin); + if (MyPageHelper.YMultiplier != 1) top += 2; + // if this broke, the bottom is defined where the parabreak occurred. + float yOffBreak = MyPageHelper.ParaBreaks.Count > 0 ? MyPageHelper.ParaBreaks[0].YOffset : 0; + if (yOffBreak > 0) + bottom = (yPageStart - yOffBreak) * MyPageHelper.YMultiplier; + else + bottom = (yPageStart - (MyParent.YBottomForBox > 0 ? MyParent.YBottomForBox : MyParent.YBottomMost)) * MyPageHelper.YMultiplier; + } + else + { + top = CalculateYOffset(yPageStart, yTopMargin); + float yOffBreak = MyPageHelper.ParaBreaks.Count > 0 ? MyPageHelper.ParaBreaks[0].YOffset : 0; + if (yOffBreak > 0) + bottom = (yPageStart - yOffBreak) * MyPageHelper.YMultiplier; + else + bottom = (yPageStart - (MyParent.YBottomForBox > 0 ? MyParent.YBottomForBox : MyParent.YBottomMost)) * MyPageHelper.YMultiplier; + top = yTopMargin; // reset top to top margin since there was a page break. + } + // Check that the bottom is within the bottom margin, if this step spans more than one page, + // stop the side asterisks at the bottom margin. (pagination puts inserts a page break here) + //_MyLog.WarnFormat("\"AS\"\t\"{0}\"\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}", MyParent, yPageStart, top, bottom, MyPageHelper.YMultiplier, MyPageHelper.CurrentPageNumber, MyParent.YBottomMost, MyParent.YBottomForBox); + if (bottom < yBottomMargin) bottom = yBottomMargin; + + float height = (SixLinesPerInch * MyPageHelper.YMultiplier) + 4; // just add a little on so that height is a little bigger than character + + // create a new font without any styles such as underline. + E_Style es = ((vef.Style & E_Style.Bold) == E_Style.Bold) ? E_Style.Bold : E_Style.None; + // if the box has a font, use it - otherwise use this item info's font + VE_Font vf = null; + bool UseBoxFont = false; + try + { + UseBoxFont = MyParent.MyItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox; + } + catch // done this way in case one of the format properties is null in the previous statement, UseBoxFont will be false. + { + } + if (UseBoxFont) + vf = new VE_Font(vef.Family, (int)vef.Size, es, (float)MyParent.MyItemInfo.FormatStepData.Font.CPI); + else + vf = new VE_Font(MyParent.MyItemInfo.FormatStepData.Font.Family, (int)MyParent.MyItemInfo.FormatStepData.Font.Size, es, (float)MyParent.MyItemInfo.FormatStepData.Font.CPI); + + // Left side first: + Rtf = GetRtf(MyBox.BXVert, vf); + IParagraph = null; // set to null so that next access of IParagraph sets the Rtf. + // start down one line because the top/bottom code draws the corner + float vertDiff = top - (SixLinesPerInch * MyPageHelper.YMultiplier); + float width = (float)(MyBox.BXVert.Length * (72 / vf.CPI)); + while (vertDiff > bottom) + { + Rtf2Pdf.TextAt(cb, IParagraph, left, vertDiff, width, height, "", yBottomMargin); + vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier); + } + + // right side: + vertDiff = top - (SixLinesPerInch * MyPageHelper.YMultiplier); + Rtf = GetRtf(MyBox.BXVert.TrimEnd(), vf); + IParagraph = null; // set to null so that next access of IParagraph sets the Rtf. + while (vertDiff > bottom) + { + Rtf2Pdf.TextAt(cb, IParagraph, right, vertDiff, width, height, "", yBottomMargin); + vertDiff -= (SixLinesPerInch * MyPageHelper.YMultiplier); + } + } + } } diff --git a/PROMS/Volian.Print.Library/vlnParagraph.cs b/PROMS/Volian.Print.Library/vlnParagraph.cs index 831828af..b59b6d3a 100644 --- a/PROMS/Volian.Print.Library/vlnParagraph.cs +++ b/PROMS/Volian.Print.Library/vlnParagraph.cs @@ -80,14 +80,13 @@ namespace Volian.Print.Library foreach (ItemInfo iChildItemInfo in itemInfoList) { if(pp != null) pp.OnStatusChanged((iChildItemInfo.DisplayNumber ?? "") == "" ? iChildItemInfo.DisplayText : iChildItemInfo.DisplayNumber, PromsPrinterStatusType.LoadVlnParagraph); - if (iChildItemInfo.IsFootnote) { vlnParagraph para = new vlnParagraph(Parent, cb, iChildItemInfo, xoff, yoff, rnoLevel, maxRNO, formatInfo, null, null, yoffRight, true, iChildItemInfo.IsSection ? pp :null); continue; // don't add it, vlnParagraph adds this item to the footnote list in ToPdf. } maxRNO = maxRnoSav; - if (iChildItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox && iChildItemInfo.IsHigh) bxIndex = null; + if (iChildItemInfo.IsHigh) bxIndex = null; if (iChildItemInfo.IsSection && (iChildItemInfo as SectionInfo).ColumnMode != maxRNO) maxRNO = (iChildItemInfo as SectionInfo).ColumnMode; int maxRnoTemplate = iChildItemInfo.TemplateChildColumnMode; @@ -348,10 +347,26 @@ namespace Volian.Print.Library int boxLnAdjust = iChildItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox ? 1 : 2; box.YOffset = para.YTop - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); boxLnAdjust = iChildItemInfo.ActiveFormat.PlantFormat.FormatData.SectData.StepSectionData.StepSectionPrintData.DiffContActBox ? 1 : 0; - box.Height = para.YBottomMost - box.YOffset - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); // para.YTop - (1.1F * vlnPrintObject.SixLinesPerInch); + + // if the YBottomForBox is set, use it to define height. Note that this property was + // introduced for IP3 continuous hls (surrounded by the asterisk box), no other format/step type uses it. + if (para.YBottomForBox > 0) + box.Height = para.YBottomForBox - box.YOffset - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); // para.YTop - (1.1F * vlnPrintObject.SixLinesPerInch); + else + box.Height = para.YBottomMost - box.YOffset - (boxLnAdjust * vlnPrintObject.SixLinesPerInch); // para.YTop - (1.1F * vlnPrintObject.SixLinesPerInch); box = null; } } + if (boxHLS) + { + // if the next HLS is boxed also, only need 1 line separating, otherwise + // need 2. + ItemInfo nxt = childItemInfo.GetNextItem(); + int nxtIsBoxed = 2; + if (nxt != null && + nxt.FormatStepData.StepLayoutData.STBoxindex != null && nxt.FormatStepData.StepLayoutData.STBoxindex >= 0) nxtIsBoxed--; + yoff += (nxtIsBoxed * vlnPrintObject.SixLinesPerInch); + } if (childItemInfo.IsSequential && childItemInfo.NextItemCount > 0 && childItemInfo.MyParent.IsHigh && ((childItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.XBlankW1stLevSub) == E_DocStructStyle.XBlankW1stLevSub)) yoff += vlnPrintObject.SixLinesPerInch; boxHLS = false; @@ -2198,6 +2213,12 @@ namespace Volian.Print.Library return YOffset + Height; } } + private float _YBottomForBox = 0; + public float YBottomForBox + { + get { return _YBottomForBox; } + set { _YBottomForBox = value; } + } private vlnParagraph GetFirstPieceLastPart() { vlnParagraph para = this; @@ -3247,13 +3268,22 @@ namespace Volian.Print.Library vlnParagraph rno = ChildrenRight[0]; vlnParagraph bottomChild = BottomChild; float xsep = MyHighLevelParagraph.XOffset + RnoOffset; - vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff, formatInfo, bottomChild == null ? true : bottomChild.MyItemInfo.HasChangeBar); + + // ip3 has an rno separator and also has asterisk boxes around continous HLS. If + // the hls has RNOs off of it, then the rno separator line is outside of the box. If + // there are RNOs, but not off of HLS, then rno separator line is within the box (this is + // how 16bit proms did this). The following use of yadjSep and YBottomForBox handle that + float yadjSep = (MyItemInfo.MyHLS.FormatStepData.StepLayoutData.STBoxindex != null && MyItemInfo.MyHLS.FormatStepData.StepLayoutData.STBoxindex >= 0 && + MyItemInfo.MyHLS.RNOs != null && MyItemInfo.MyHLS.RNOs.Count > 0) ? 2 * SixLinesPerInch : 0; + vlnRNOSeparator myRnoSep = new vlnRNOSeparator(this, cb, tmpRnoSepStr, xsep, yoff+yadjSep, formatInfo, bottomChild == null ? true : bottomChild.MyItemInfo.HasChangeBar); // TODO: May need to handle more than one RNO column for RNO Separator if (rno.LastRNO.MyItemInfo.HasChangeBar == false && bottomChild != null && bottomChild.MyItemInfo.HasChangeBar) bottomChild.PartsBelow.Add(myRnoSep); else rno.LastRNO.PartsBelow.Add(myRnoSep); - yoff += myRnoSep.Height + SixLinesPerInch; + MyHighLevelParagraph.YBottomForBox = 0; + if (yadjSep>0) MyHighLevelParagraph.YBottomForBox = yoff; // if hlrno, box before sep + yoff += (myRnoSep.Height + SixLinesPerInch); } YBottomMost = yoff;