/// <summary> /// We need to start the text /// </summary> protected virtual bool StartText() { if (this.Context.ShouldLogDebug) { this.Context.TraceLog.Begin(TraceLevel.Verbose, LOG_CATEGORY, "Starting the layout of text component " + this.TextComponent.ID); } bool started; PDFLayoutLine line = this.EnsureFirstLineAvailable(out started); if (null == line) { this.ContinueLayout = false; return(false); } this.CurrentLine = line; this.Context.Graphics.SetCurrentFont(this.TextRenderOptions.Font); PDFUnit inset = PDFUnit.Zero; if (line.IsEmpty == false) { inset = line.Width; } else if (this.TextRenderOptions.FirstLineInset.HasValue && (this.Position.PositionMode != PositionMode.Inline || started)) { inset = this.TextRenderOptions.FirstLineInset.Value; if (inset > 0) { PDFTextRunSpacer spacer = new PDFTextRunSpacer(inset, 1, line, null); line.AddRun(spacer); } } PDFTextRunBegin begin = new PDFTextRunBegin(this.TextRenderOptions, this.CurrentLine, this.TextComponent); begin.LineInset = inset; this.CurrentLine.AddRun(begin); begin.SetOffsetY(this.CurrentLine.OffsetY); this.CurrentLineInset = inset; this.BeginningRun = begin; if (this.Context.ShouldLogDebug) { this.Context.TraceLog.End(TraceLevel.Verbose, LOG_CATEGORY, "Completed the layout of text component " + this.TextComponent.ID); } else if (this.Context.ShouldLogVerbose) { this.Context.TraceLog.Add(TraceLevel.Verbose, LOG_CATEGORY, "Laid out text component " + this.TextComponent.ID); } return(true); }
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); }
// // ctor // public PDFTextRunEnd(PDFTextRunBegin start, PDFLayoutLine line, IPDFComponent owner) : base(line, owner) { this._start = start; }