public Boolean IsEqual ( TextSeg Other ) { return(this.Font == Other.Font && this.FontSize == Other.FontSize && this.DrawStyle == Other.DrawStyle && this.FontColor == Other.FontColor); }
public TextSeg ( TextSeg CopySeg ) { this.Font = CopySeg.Font; this.FontSize = CopySeg.FontSize; this.DrawStyle = CopySeg.DrawStyle; this.FontColor = CopySeg.FontColor; Text = String.Empty; return; }
private void BreakLine() { // break segment at line break seg index into two segments TextSeg BreakSeg = SegArray[BreakSegIndex]; // add extra segment to segment array if (BreakPtr != 0) { TextSeg ExtraSeg = new TextSeg(BreakSeg); ExtraSeg.SegWidth = BreakWidth; ExtraSeg.Text = BreakSeg.Text.Substring(0, BreakPtr); SegArray.Insert(BreakSegIndex, ExtraSeg); BreakSegIndex++; } // remove blanks from the area between the two sides of the segment for (; BreakPtr < BreakSeg.Text.Length && BreakSeg.Text[BreakPtr] == ' '; BreakPtr++) { ; } // save the area after the first line if (BreakPtr < BreakSeg.Text.Length) { BreakSeg.Text = BreakSeg.Text.Substring(BreakPtr); BreakSeg.SegWidth = BreakSeg.Font.TextWidth(BreakSeg.FontSize, BreakSeg.Text); } else { BreakSeg.Text = String.Empty; BreakSeg.SegWidth = 0.0; } BreakPtr = 0; BreakWidth = 0.0; return; }
private void AddLine ( Boolean EndOfParagraph ) { // end of paragraph if (EndOfParagraph) { BreakSegIndex = SegArray.Count; } // test for possible trailing blanks if (SegArray[BreakSegIndex - 1].Text.EndsWith(" ")) { // remove trailing blanks while (BreakSegIndex > 0) { TextSeg TempSeg = SegArray[BreakSegIndex - 1]; TempSeg.Text = TempSeg.Text.TrimEnd(new Char[] { ' ' }); TempSeg.SegWidth = TempSeg.Font.TextWidth(TempSeg.FontSize, TempSeg.Text); if (TempSeg.Text.Length != 0 || BreakSegIndex == 1 && EndOfParagraph) { break; } BreakSegIndex--; SegArray.RemoveAt(BreakSegIndex); } } // test for abnormal case of a blank line and not end of paragraph if (BreakSegIndex > 0) { // allocate segment array TextSeg[] LineSegArray = new TextSeg[BreakSegIndex]; // copy segments SegArray.CopyTo(0, LineSegArray, 0, BreakSegIndex); // line ascent and descent Double LineAscent = 0; Double LineDescent = 0; // loop for segments until line break segment index foreach (TextSeg Seg in LineSegArray) { Double Ascent = Seg.Font.AscentPlusLeading(Seg.FontSize); if (Ascent > LineAscent) { LineAscent = Ascent; } Double Descent = Seg.Font.DescentPlusLeading(Seg.FontSize); if (Descent > LineDescent) { LineDescent = Descent; } Int32 SpaceCount = 0; foreach (Char Chr in Seg.Text) { if (Chr == ' ') { SpaceCount++; } } Seg.SpaceCount = SpaceCount; } // add line LineArray.Add(new TextLine(LineAscent, LineDescent, EndOfParagraph, LineSegArray)); // update column height _BoxHeight += LineAscent + LineDescent; // update paragraph count if (EndOfParagraph) { _ParagraphCount++; } // remove segments SegArray.RemoveRange(0, BreakSegIndex); } // switch to next line LineBreakWidth = 0.0; BreakSegIndex = 0; // new line width LineWidth = 0.0; foreach (TextSeg Seg in SegArray) { LineWidth += Seg.SegWidth; } return; }
public void AddText ( PdfFont Font, Double FontSize, DrawStyle DrawStyle, Color FontColor, String Text, String WebLink ) { // text is null or empty if (String.IsNullOrEmpty(Text)) { return; } // create new text segment TextSeg Seg; // segment array is empty or new segment is different than last one if (SegArray.Count == 0 || !SegArray[SegArray.Count - 1].IsEqual(Font, FontSize, DrawStyle, FontColor, WebLink)) { Seg = new TextSeg(Font, FontSize, DrawStyle, FontColor, WebLink); SegArray.Add(Seg); } // add new text to most recent text segment else { Seg = SegArray[SegArray.Count - 1]; } // save text start pointer Int32 TextStart = 0; // loop for characters for (Int32 TextPtr = 0; TextPtr < Text.Length; TextPtr++) { // shortcut to current character Char CurChar = Text[TextPtr]; // end of paragraph if (CurChar == '\n' || CurChar == '\r') { // append text to current segemnt Seg.Text += Text.Substring(TextStart, TextPtr - TextStart); // test for new line after carriage return if (CurChar == '\r' && TextPtr + 1 < Text.Length && Text[TextPtr + 1] == '\n') { TextPtr++; } // move pointer to one after the eol TextStart = TextPtr + 1; // add line AddLine(true); // update last character PrevChar = ' '; // end of text if (TextPtr + 1 == Text.Length) { return; } // add new empty segment Seg = new TextSeg(Font, FontSize, DrawStyle, FontColor, WebLink); SegArray.Add(Seg); continue; } // validate character Font.ValidateChar(CurChar); // character width Double CharWidth = Font.CharWidth(FontSize, Seg.DrawStyle, CurChar); // space if (CurChar == ' ') { // test for transition from non space to space // this is a potential line break point if (PrevChar != ' ') { // save potential line break information LineBreakWidth = LineWidth; BreakSegIndex = SegArray.Count - 1; BreakPtr = Seg.Text.Length + TextPtr - TextStart; BreakWidth = Seg.SegWidth; } // add to line width LineWidth += CharWidth; Seg.SegWidth += CharWidth; // update last character PrevChar = CurChar; continue; } // add current segment width and to overall line width Seg.SegWidth += CharWidth; LineWidth += CharWidth; // for next loop set last character PrevChar = CurChar; Double Width = _BoxWidth; if (_FirstLineIndent != 0 && (LineArray.Count == 0 || LineArray[LineArray.Count - 1].EndOfParagraph)) { Width -= _FirstLineIndent; } // current line width is less than or equal box width if (LineWidth <= Width) { continue; } // append text to current segemnt Seg.Text += Text.Substring(TextStart, TextPtr - TextStart + 1); TextStart = TextPtr + 1; // there are no breaks in this line or last segment is too long if (LineBreakWidth < LineBreakFactor * Width) { BreakSegIndex = SegArray.Count - 1; BreakPtr = Seg.Text.Length - 1; BreakWidth = Seg.SegWidth - CharWidth; } // break line BreakLine(); // add line up to break point AddLine(false); } // save text Seg.Text += Text.Substring(TextStart); // exit return; }