/// <summary> /// The height of a block of lines within TextBox not excedding request height. /// </summary> /// <param name="LineStart">Start line</param> /// <param name="LineEnd">End line</param> /// <param name="RequestHeight">Requested height</param> /// <param name="LineExtraSpace">Extra line space.</param> /// <param name="ParagraphExtraSpace">Extra paragraph space.</param> /// <returns>Height</returns> /// <remarks> /// LineStart will be adjusted forward to skip blank lines. LineEnd /// will be one after a non blank line. /// </remarks> public double BoxHeightExtra ( ref int LineStart, out int LineEnd, double RequestHeight, double LineExtraSpace, double ParagraphExtraSpace ) { // skip blank lines for (; LineStart < LineArray.Count; LineStart++) { TextBoxLine Line = LineArray[LineStart]; if (!Line.EndOfParagraph || Line.SegArray.Length > 1 || Line.SegArray[0].SegWidth != 0) { break; } } // end of textbox if (LineStart >= LineArray.Count) { LineStart = LineEnd = LineArray.Count; return(0.0); } // calculate height for requested line count double Total = 0.0; double Height = 0.0; int End = LineEnd = LineStart; for (;;) { TextBoxLine Line = LineArray[End]; if (Total + Line.LineHeight > RequestHeight) { break; } Total += Line.LineHeight; End++; if (!Line.EndOfParagraph || Line.SegArray.Length > 1 || Line.SegArray[0].SegWidth != 0) { LineEnd = End; Height = Total; } if (End == LineCount) { break; } Total += LineExtraSpace; if (Line.EndOfParagraph) { Total += ParagraphExtraSpace; } } return(Height); }
/// <summary> /// Terminate TextBox /// </summary> public void Terminate() { // terminate last line if(SegArray.Count != 0) AddLine(true); // remove trailing empty paragraphs for(Int32 Index = LineArray.Count - 1; Index >= 0; Index--) { TextBoxLine Line = LineArray[Index]; if(!Line.EndOfParagraph || Line.SegArray.Length > 1 || Line.SegArray[0].SegWidth != 0) break; BoxHeight -= Line.Ascent + Line.Descent; ParagraphCount--; LineArray.RemoveAt(Index); } // exit return; }
/// <summary> /// Thwe height of the first LineCount lines including extra line and paragraph space. /// </summary> /// <param name="LineCount">The requested number of lines.</param> /// <param name="LineExtraSpace">Extra line space.</param> /// <param name="ParagraphExtraSpace">Extra paragraph space.</param> /// <returns>Height</returns> public double BoxHeightExtra ( int LineCount, double LineExtraSpace, double ParagraphExtraSpace ) { // textbox is empty if (LineArray.Count == 0) { return(0.0); } // line count is greater than available lines if (LineCount >= LineArray.Count) { return(BoxHeightExtra(LineExtraSpace, ParagraphExtraSpace)); } // calculate height for requested line count double Height = 0; for (int Index = 0; ; Index++) { TextBoxLine Line = LineArray[Index]; Height += Line.LineHeight; if (Index + 1 == LineCount) { break; } Height += LineExtraSpace; if (Line.EndOfParagraph) { Height += ParagraphExtraSpace; } } return(Height); }
//////////////////////////////////////////////////////////////////// // Stretch text to given width //////////////////////////////////////////////////////////////////// private Boolean TextFitToWidth( Double ReqWidth, out Double WordSpacing, out Double CharSpacing, TextBoxLine Line ) { WordSpacing = 0; CharSpacing = 0; Int32 CharCount = 0; Double Width = 0; Int32 SpaceCount = 0; Double SpaceWidth = 0; foreach(TextBoxSeg Seg in Line.SegArray) { // accumulate line width CharCount += Seg.Text.Length; Width += Seg.SegWidth; // count spaces SpaceCount += Seg.SpaceCount; // accumulate space width SpaceWidth += Seg.SpaceCount * Seg.Font.CharWidth(Seg.FontSize, ' '); } // reduce character count by one CharCount--; if(CharCount <= 0) return(false); // extra spacing required Double ExtraSpace = ReqWidth - Width; // highest possible output device resolution (12000 dots per inch) Double MaxRes = 0.006 / ScaleFactor; // string is too wide if(ExtraSpace < (-MaxRes)) return(false); // string is just right if(ExtraSpace < MaxRes) return(true); // String does not have any blank characters if(SpaceCount == 0) { CharSpacing = ExtraSpace / CharCount; return(true); } // extra space per word WordSpacing = ExtraSpace / SpaceCount; // extra space is equal or less than one blank if(WordSpacing <= SpaceWidth / SpaceCount) return(true); // extra space is larger that one blank // increase character and word spacing CharSpacing = ExtraSpace / (10 * SpaceCount + CharCount); WordSpacing = 10 * CharSpacing; return(true); }
//////////////////////////////////////////////////////////////////// // Draw text justify to width within text box //////////////////////////////////////////////////////////////////// private Double DrawText( Double PosX, Double PosY, Double Width, TextBoxLine Line, PdfPage Page ) { Double WordSpacing; Double CharSpacing; if(!TextFitToWidth(Width, out WordSpacing, out CharSpacing, Line)) return(DrawText(PosX, PosY, Line, Page)); SaveGraphicsState(); SetWordSpacing(WordSpacing); SetCharacterSpacing(CharSpacing); Double SegPosX = PosX; foreach(TextBoxSeg Seg in Line.SegArray) { Double SegWidth = DrawText(Seg.Font, Seg.FontSize, SegPosX, PosY, TextJustify.Left, Seg.DrawStyle, Seg.FontColor, Seg.Text) + Seg.SpaceCount * WordSpacing + Seg.Text.Length * CharSpacing; if(Seg.WebLink != null) { if(Page == null) throw new ApplicationException("TextBox with WebLink. You must call DrawText with PdfPage"); Page.AddWebLink(SegPosX, PosY - Seg.Font.DescentPlusLeading(Seg.FontSize), SegPosX + SegWidth, PosY + Seg.Font.AscentPlusLeading(Seg.FontSize), Seg.WebLink); } SegPosX += SegWidth; } RestoreGraphicsState(); return(SegPosX - PosX); }
//////////////////////////////////////////////////////////////////// // Draw text within text box center or right justified //////////////////////////////////////////////////////////////////// private Double DrawText( Double PosX, Double PosY, Double Width, TextBoxJustify Justify, TextBoxLine Line, PdfPage Page ) { Double LineWidth = 0; foreach(TextBoxSeg Seg in Line.SegArray) LineWidth += Seg.SegWidth; Double SegPosX = PosX; if(Justify == TextBoxJustify.Right) SegPosX += Width - LineWidth; else SegPosX += 0.5 * (Width - LineWidth); foreach(TextBoxSeg Seg in Line.SegArray) { Double SegWidth = DrawText(Seg.Font, Seg.FontSize, SegPosX, PosY, TextJustify.Left, Seg.DrawStyle, Seg.FontColor, Seg.Text); if(Seg.WebLink != null) { if(Page == null) throw new ApplicationException("TextBox with WebLink. You must call DrawText with PdfPage"); Page.AddWebLink(SegPosX, PosY - Seg.Font.DescentPlusLeading(Seg.FontSize), SegPosX + SegWidth, PosY + Seg.Font.AscentPlusLeading(Seg.FontSize), Seg.WebLink); } SegPosX += SegWidth; } return(SegPosX - PosX); }