Пример #1
0
        protected override void DoLayoutTextComponent(IPDFTextComponent text, Style style)
        {
            var region = this.Context.DocumentLayout.CurrentPage.LastOpenBlock().CurrentRegion;

            var line = region.CurrentItem as PDFLayoutLine;

            if (null == line)
            {
                line = region.BeginNewLine();
            }

            var bmc = line.AddMarkedContentStart(this, this.Component, PDFMarkedContentType.Text);

            base.DoLayoutTextComponent(text, style);

            if (this._addedProxyText)
            {
                for (int i = line.Runs.Count - 1; i >= 0; i--)
                {
                    if (line.Runs[i] is PDFTextRunCharacter)
                    {
                        PDFTextRunCharacter chars = (PDFTextRunCharacter)line.Runs[i];
                        chars.Characters = "";
                        break;
                    }
                }
            }
            line.AddMarkedContentEnd(this, bmc);
        }
        /// <summary>
        /// Creates a new Text character run and adds it to the current line.
        /// </summary>
        /// <param name="size">the size of the run in PDFUnits</param>
        /// <param name="chars">The characters that should be rendered in the run</param>
        private void AddCharactersToCurrentLine(PDFSize size, string chars)
        {
            this.AssertCurrentLine();

            PDFTextRunCharacter run = new PDFTextRunCharacter(size, chars, this.CurrentLine, this.TextComponent);

            this.CurrentLine.AddRun(run);
        }
        private bool EndsInASpace(PDFTextRunCharacter runChars)
        {
            if (string.IsNullOrEmpty(runChars.Characters))
            {
                return(false);
            }
            char last = runChars.Characters[runChars.Characters.Length - 1];

            return(last == ' ');
        }
Пример #4
0
        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);
        }
        protected virtual void RenderTextDecoration(PDFTextRunEnd endRun, PDFRenderContext context, PDFWriter writer, PDFUnit vOffset, PDFUnit linethickness)
        {
            if (context.ShouldLogDebug)
            {
                context.TraceLog.Begin(TraceLevel.Debug, "Text Decoration", "Starting to render text decorations");
            }

            //set up the graphics context
            PDFPen pen = PDFPen.Create(this.TextRenderOptions.FillBrush, linethickness);

            context.Graphics.SaveGraphicsState();
            pen.SetUpGraphics(context.Graphics, this.TotalBounds);

            bool     drawing   = false;
            PDFPoint linestart = new PDFPoint(this.StartTextCursor.Width, this.StartTextCursor.Height + vOffset);


            foreach (PDFLayoutLine line in this.Lines)
            {
                PDFUnit linewidth = 0;

                foreach (PDFLayoutRun run in line.Runs)
                {
                    if (run == this)
                    {
                        drawing = true;
                        //lineoffset += this.LineInset;
                    }
                    else if (run == endRun)
                    {
                        drawing = false;
                        break;
                    }
                    else if (drawing)
                    {
                        if (run is PDFTextRunCharacter)
                        {
                            PDFTextRunCharacter chars = (PDFTextRunCharacter)run;
                            PDFPoint            start = new PDFPoint(linestart.X + linewidth, linestart.Y);
                            PDFPoint            end   = new PDFPoint(linestart.X + linewidth + chars.Width + chars.ExtraSpace, linestart.Y);
                            context.Graphics.DrawLine(start, end);
                            if (context.ShouldLogDebug)
                            {
                                context.TraceLog.Add(TraceLevel.Debug, "Text Decoration", "Drawn line from " + start + " to " + end);
                            }
                            linewidth += chars.Width;
                        }
                        else if (run is PDFTextRunEnd)
                        {
                        }
                        else if (run is PDFTextRunNewLine)
                        {
                            PDFTextRunNewLine newline = (PDFTextRunNewLine)run;
                            PDFSize           offset  = newline.Offset;
                            if (null != newline.NextLineSpacer)
                            {
                                PDFUnit nextoffset = newline.NextLineSpacer.Width;
                                offset.Width = nextoffset - offset.Width;
                            }
                            linestart.X += offset.Width;
                            linestart.Y += offset.Height;
                        }
                        else if (run is PDFTextRunSpacer)
                        {
                            //PDFTextRunSpacer spacer = (PDFTextRunSpacer)run;
                            //cursor.X += spacer.Width;
                        }
                        else if (run is PDFTextRunProxy)
                        {
                            PDFTextRunProxy chars = (PDFTextRunProxy)run;
                            PDFPoint        start = new PDFPoint(linestart.X + linewidth, linestart.Y);
                            PDFPoint        end   = new PDFPoint(linestart.X + linewidth + chars.Width, linestart.Y);
                            context.Graphics.DrawLine(start, end);
                            if (context.ShouldLogDebug)
                            {
                                context.TraceLog.Add(TraceLevel.Debug, "Text Decoration", "Drawn line from " + start + " to " + end);
                            }
                            linewidth += chars.Width;
                        }
                    }
                }
            }

            if (context.ShouldLogDebug)
            {
                context.TraceLog.End(TraceLevel.Debug, "Text Decoration", "Completed the renderering of text decorations");
            }

            //tear down the current graphics state
            context.Graphics.RestoreGraphicsState();
        }