/// <summary> /// Add characters to the line(s), and returns the last width of the characters that were laid out. /// </summary> protected virtual PDFUnit AddCharacters(string chars) { this.AssertCurrentLine(); PDFUnit lineheight = this.TextRenderOptions.GetLineHeight(); int offset = 0; ZeroLineCounter zeros = new ZeroLineCounter(); PDFSize measured = PDFSize.Empty; PDFSize required = PDFSize.Empty; while (offset < chars.Length) { //Check that we have enough space for the next line PDFLayoutLine line = this.CurrentLine; PDFLayoutRegion reg = line.Region; PDFUnit availH = reg.AvailableHeight; PDFUnit availW = line.AvailableWidth; if (availH < lineheight) { if (this.Position.OverflowAction != OverflowAction.Clip) { this.DoMoveToNextRegion(lineheight); if (!this.ContinueLayout) { return(PDFUnit.Zero); } else { line = this.CurrentLine; reg = line.Region; availW = line.AvailableWidth; availH = reg.AvailableHeight; } } else { availH = lineheight; } } //Measure the string an get the fitted characters Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Measure); int fitted; measured = this.MeasureString(availH, availW, chars, offset, out fitted); Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Measure); required = new PDFSize(measured.Width, lineheight); if (fitted <= 0) //nothing fitted on the line { this.AddSoftReturn(0); if (!zeros.AssertIncrement(this.Context)) { return(PDFUnit.Zero); } } else if (fitted + offset == chars.Length) // everything fitted on the line { zeros.Reset(); string all = chars.Substring(offset); //if (offset == 0) this.AddCharactersToCurrentLine(required, all); //else // this.AddCharactersToCurrentLine(required, chars, offset, fitted); offset += fitted; } else if (IsBrokenInWord(chars, offset, fitted) && CanSplitOnWordsOnly() && !IsEmptyLine()) //don't break on words unless we have to. { this.AddSoftReturn(0); if (!zeros.AssertIncrement(this.Context)) { return(PDFUnit.Zero); } } else //partial fit { zeros.Reset(); string partial = chars.Substring(offset, fitted); this.AddCharactersToCurrentLine(required, partial); //this.AddCharactersToCurrentLine(required, chars, offset, fitted); this.AddSoftReturn(measured.Width); offset += fitted; //Consume any white space as we are now on a new line. //We should never get here for NoWrap as it will alywys fit all characters one one line. while (offset < chars.Length && char.IsWhiteSpace(chars, offset)) { offset++; } } } return(required.Width); }
/// <summary> /// Add characters to the line(s), and returns the last width of the characters that were laid out. /// </summary> protected virtual PDFUnit AddProxyCharacters(PDFTextProxyOp proxy) { this.AssertCurrentLine(); PDFUnit lineheight = this.TextRenderOptions.GetLineHeight(); ZeroLineCounter zeros = new ZeroLineCounter(); PDFSize measured = PDFSize.Empty; PDFSize required = PDFSize.Empty; PDFLayoutLine line = this.CurrentLine; PDFLayoutRegion reg = line.Region; PDFUnit availH = reg.AvailableHeight; PDFUnit availW = line.AvailableWidth; if (availH < lineheight) { if (this.Position.OverflowAction != OverflowAction.Clip) { availH = lineheight; } else { this.DoMoveToNextRegion(lineheight); if (!this.ContinueLayout) { return(PDFUnit.Zero); } } } //Measure the string an get the fitted characters int fitted; this.Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Measure); measured = this.MeasureString(availH, availW, proxy.Text, 0, out fitted); this.Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Measure); required = new PDFSize(measured.Width, lineheight); if (fitted < proxy.Text.Length) //cannot split a proxy - must simply be a single run. { //try on the next line to see if we can put everything on there. this.AddSoftReturn(0); if (!zeros.AssertIncrement(this.Context)) { return(PDFUnit.Zero); } availW = this.CurrentLine.AvailableWidth; this.Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Measure); measured = this.MeasureString(availH, availW, proxy.Text, 0, out fitted); this.Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Measure); if (fitted < proxy.Text.Length) //Still cannot fit the proxy so not much we can do. Log it and return { this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "The text proxy for '" + proxy.Text + "' could not fit the characters on a single line. Overflow of proxies is not currently supported."); return(measured.Width); } required = new PDFSize(measured.Width, lineheight); } // everything fitted on the line zeros.Reset(); this.AddProxyToCurrentLine(required, proxy); return(required.Width); }