コード例 #1
0
        protected virtual void AddReturn(PDFUnit widthOfLastTextDraw, bool hardReturn)
        {
            this.AssertCurrentLine();
            PDFLayoutLine     line = this.CurrentLine;
            PDFTextRunNewLine br   = new PDFTextRunNewLine(false, line, this.TextRenderOptions, this.TextComponent);


            line.AddRun(br);

            //The offset is from the start of the last text drawing operation
            //and the offset of the start of the current line
            PDFUnit lineright = widthOfLastTextDraw;

            PDFUnit back = line.Width - lineright;

            //Previous - 27 Feb 2015
            //br.Offset = new PDFSize(back, line.Height);

            //Updated
            if (line.BaseLineOffset == 0 || this.TextRenderOptions.Leading.HasValue) //we don't have any begins or ends affecting the flow (or an explicit leading)
            {
                br.Offset = new PDFSize(back, line.Height);
            }
            else
            {
                br.Offset = new PDFSize(back, (line.Height - line.BaseLineOffset) + this.TextRenderOptions.GetAscent());
            }


            PDFLayoutRegion reg = line.Region;

            reg.CloseCurrentItem();
            line = reg.BeginNewLine();
            this.BeginningRun.Lines.Add(line);

            PDFUnit inset;

            if (hardReturn)
            {
                inset = this.TextRenderOptions.GetFirstLineInset();
            }
            else
            {
                inset = PDFUnit.Zero;
            }

            PDFTextRunSpacer spacer = this.AddLineInsetRun(inset, 0, line);

            br.NextLineSpacer     = spacer;
            this.CurrentLine      = line;
            this.CurrentLineInset = inset;
        }
コード例 #2
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);
        }
コード例 #3
0
        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();
        }