/// <summary> /// Adds the component to the line using <i>all</i> the provided options /// </summary> /// <param name="comp">the component to add to the line</param> /// <param name="total">the total bounds of the component</param> /// <param name="border">the border rectangle wrt the total bounds</param> /// <param name="content">the content rectangle wrt the total bounds</param> /// <param name="baselineOffset">The required offset of the baseline of this line from it's top</param> /// <param name="options">the positioning options</param> /// <param name="style">the full style of the component</param> /// <returns>The created run</returns> public virtual PDFLayoutRun AddComponentRun(IPDFComponent comp, PDFRect total, PDFRect border, PDFRect content, PDFUnit baselineOffset, PDFPositionOptions options, Style style) { PDFLayoutComponentRun comprun = new PDFLayoutComponentRun(this, comp, style); this.Runs.Add(comprun); total = total.Offset(this.Width, this.OffsetY); comprun.InitSize(total, border, content, options); comprun.Close(); //Added 13th June 2016 this.BaseLineOffset = PDFUnit.Max(this.BaseLineOffset, baselineOffset); return(comprun); }
internal bool JustifyContent(PDFUnit total, PDFUnit current, PDFUnit available, bool all, List <PDFTextRunCharacter> runCache, ref PDFTextRenderOptions currOptions) { if (this.Runs.Count < 1) { return(false); } bool shouldJustify = all; PDFLayoutRun last = this.Runs[this.Runs.Count - 1]; if (last is PDFTextRunNewLine && (last as PDFTextRunNewLine).IsHardReturn == false) { shouldJustify = true; } if (shouldJustify) { runCache.Clear(); bool intext = (null != currOptions); //if we have text render options then even if we are the first run we can be considered as inside a text block int charCount = 0; int spaceCount = 0; PDFTextRunCharacter lastchars = null; for (int i = 0; i < this.Runs.Count; i++) { PDFLayoutRun cur = this.Runs[i]; if (cur is PDFTextRunBegin) { currOptions = ((PDFTextRunBegin)cur).TextRenderOptions; if (!intext) { intext = true; } } else if (cur is PDFTextRunCharacter && intext) { PDFTextRunCharacter chars = cur as PDFTextRunCharacter; if (!(currOptions.WordSpacing.HasValue || currOptions.CharacterSpacing.HasValue)) { AddCharactersAndSpaces(chars.Characters, ref charCount, ref spaceCount); lastchars = chars; } } else if (cur is PDFLayoutComponentRun) { lastchars = null; } } // Post process to calculate the required spacing // if we have some text in our line. if (intext && (spaceCount + charCount > 0)) { if (null != lastchars && lastchars.Characters.EndsWith(" ")) { lastchars.Characters = lastchars.Characters.Substring(0, lastchars.Characters.Length - 1); spaceCount -= 1; } double spaceToCharFactor = 10; // apply ten times more to spaces than characters. double full = (spaceCount * spaceToCharFactor) + charCount; this._linespacingOptions = new ExtraSpacingOptions() { CharSpace = available / full, WordSpace = (available / full) * spaceToCharFactor, Options = currOptions }; charCount = 0; spaceCount = 0; PDFUnit currWidth = 0; PDFUnit change = PDFUnit.Zero; for (int i = 0; i < this.Runs.Count; i++) { PDFLayoutRun cur = this.Runs[i]; if (cur is PDFTextRunBegin) { PDFTextRunBegin begin = (PDFTextRunBegin)cur; currOptions = begin.TextRenderOptions; if (i > 0) { change = (_linespacingOptions.WordSpace * spaceCount) + (_linespacingOptions.CharSpace * charCount); begin.LineInset += change; } } else if (cur is PDFTextRunCharacter) { if (!currOptions.WordSpacing.HasValue || !currOptions.CharacterSpacing.HasValue) { PDFTextRunCharacter chars = cur as PDFTextRunCharacter; int runChars = 0; int runSpaces = 0; AddCharactersAndSpaces(chars.Characters, ref runChars, ref runSpaces); charCount += runChars; spaceCount += runSpaces; chars.ExtraSpace = (_linespacingOptions.WordSpace * runSpaces) + (_linespacingOptions.CharSpace * runChars); } } else if (cur is PDFLayoutComponentRun) { if (i > 0) { PDFLayoutComponentRun comprun = (cur as PDFLayoutComponentRun); PDFRect bounds = comprun.TotalBounds; bounds.X += (_linespacingOptions.WordSpace * spaceCount) + (_linespacingOptions.CharSpace * charCount); comprun.TotalBounds = bounds; } } else if (cur is PDFTextRunNewLine) { PDFTextRunNewLine newLine = (cur as PDFTextRunNewLine); newLine.Offset = new PDFSize(newLine.Offset.Width + change, newLine.Offset.Height); } } } } return(shouldJustify); }