コード例 #1
0
 public void ResetJustifySpacing(PDFTextRenderOptions options)
 {
     _linespacingOptions = new ExtraSpacingOptions()
     {
         WordSpace = PDFUnit.Zero, CharSpace = PDFUnit.Zero, Options = options
     };
 }
コード例 #2
0
        public void SetTextLeading(PDFTextRenderOptions options)
        {
            PDFUnit h;

            if (options.Leading.HasValue)
            {
                h = options.Leading.Value;
            }
            else if (options.Font.FontMetrics != null)
            {
                h = options.Font.FontMetrics.LineHeight;
            }
            else if (null != this.CurrentFontResource && options.Font != null && this.CurrentFontResource.FontName == options.Font.FullName)
            {
                options.Font.FontMetrics = this.CurrentFontResource.Definition.GetFontMetrics(options.Font.Size);
                h = options.Font.FontMetrics.LineHeight;
            }

            else
            {
                h = options.Font.Size.PointsValue * 1.2;
            }

            this.Writer.WriteOpCodeS(PDFOpCode.TxtLeading, h.RealValue);
        }
コード例 #3
0
 private System.Drawing.Font GetSystemFont(PDFTextRenderOptions options)
 {
     //if (options == null || options.Font == null)
     return(null);
     //else
     //   return options.Font.GetSystemFont();
 }
コード例 #4
0
        /// <summary>
        /// Measures all the characters on a specified string returning their size
        /// 6based on how many fitted in the available space.
        /// </summary>
        /// <param name="chars"></param>
        /// <param name="offset"></param>
        /// <param name="fitted"></param>
        /// <param name="availh">The available height in the current region</param>
        /// <returns></returns>
        private PDFSize MeasureString(PDFUnit availh, PDFUnit availw, string chars, int offset, out int fitted)
        {
            PDFSize available         = new PDFSize(availw, availh);
            PDFTextRenderOptions opts = this.TextRenderOptions;

            PDFSize measured;

            measured = this.Context.Graphics.MeasureString(chars, offset, available, opts, out fitted);
            return(measured);
        }
コード例 #5
0
 private void ReleaseTextRenderOptions(PDFTextRenderOptions options, PDFRect bounds)
 {
     if (options.FillBrush != null)
     {
         options.FillBrush.ReleaseGraphics(this, bounds);
     }
     if (options.Stroke != null)
     {
         options.Stroke.ReleaseGraphics(this, bounds);
     }
 }
コード例 #6
0
 private double GetLineLeft(PDFSize size, PDFTextRenderOptions options)
 {
     if (options != null && options.FirstLineInset != PDFUnit.Empty)
     {
         return(options.FirstLineInset.Value.ToPoints().Value);
     }
     else
     {
         return(0.0);
     }
 }
コード例 #7
0
        public void SetTextSpacing(PDFTextRenderOptions options)
        {
            if (options.WordSpacing.HasValue == false)
            {
                this.ResetCustomWordSpace();
            }
            SetTextSpacing(options.WordSpacing, options.CharacterSpacing, options.Font.Size);

            if (options.CharacterHScale.HasValue)
            {
                this.Writer.WriteOpCodeS(PDFOpCode.TxtHScaling, (PDFReal)options.CharacterHScale.Value * 100.0);
            }
        }
コード例 #8
0
        private static StringFormat GetStringFormatting(PDFTextRenderOptions options)
        {
            StringFormat format;

            if (options.WrapText.HasValue && options.WrapText.Value == WordWrap.Character)
            {
                format = NoWrappingCharacterFormant;
            }
            else
            {
                format = NoWrappingWordFormat;
            }
            return(format);
        }
コード例 #9
0
        public TextRenderMode SetTextRenderOptions(PDFTextRenderOptions options, PDFRect bounds)
        {
            TextRenderMode mode = TextRenderMode.NoOp;

            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (options.FillBrush != null)
            {
                mode = TextRenderMode.Fill;
                options.FillBrush.SetUpGraphics(this, bounds);
            }
            if (options.Stroke != null)
            {
                if (mode == TextRenderMode.Fill)
                {
                    mode = TextRenderMode.FillAndStroke;
                }
                else
                {
                    mode = TextRenderMode.Stroke;
                }

                options.Stroke.SetUpGraphics(this, bounds);
            }
            if (options.Font != null)
            {
                this.SetCurrentFont(options.Font);
            }

            if (options.TextDirection.HasValue)
            {
                this.TextDirection = options.TextDirection.Value;
            }
            else
            {
                this.TextDirection = Scryber.TextDirection.LTR;
            }

            SetTextLeading(options);
            SetTextSpacing(options);
            SetTextRenderMode(mode);
            return(mode);
        }
コード例 #10
0
        public void SetTextLeading(PDFTextRenderOptions options)
        {
            PDFUnit h;

            if (options.Leading.HasValue)
            {
                h = options.Leading.Value;
            }
            else if (options.Font.FontMetrics != null)
            {
                h = options.Font.FontMetrics.LineHeight;
            }
            else
            {
                h = options.Font.Size.PointsValue * 1.2;
            }

            this.Writer.WriteOpCodeS(PDFOpCode.TxtLeading, h.RealValue);
        }
コード例 #11
0
        //
        // layout methods
        //

        #region public void Layout(PDFLayoutContext context, Styles.PDFStyle fullstyle)

        /// <summary>
        /// Measures and lay's out the TextComponent that this engine references.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="fullstyle"></param>
        public void Layout(PDFLayoutContext context, Styles.Style fullstyle)
        {
            if (null == context)
            {
                throw new ArgumentNullException("context");
            }
            if (null == fullstyle)
            {
                throw new ArgumentNullException("fullstyle");
            }


            this._ctx       = context;
            this._fullstyle = fullstyle;


            this._posopts  = fullstyle.CreatePostionOptions();
            this._textopts = fullstyle.CreateTextOptions();

            if (this._posopts.PositionMode == PositionMode.Invisible)
            {
                if (context.ShouldLogDebug)
                {
                    context.TraceLog.Add(TraceLevel.Debug, "Layout", "Skipping the layout of the text component " + this.TextComponent.ID + " as it is invisible");
                }
                return;
            }

            this._frsrc = ((Document)this.TextComponent.Document).GetFontResource(this.TextRenderOptions.Font, true);

            this.Context.PerformanceMonitor.Begin(PerformanceMonitorType.Text_Layout);

            this._reader = this.TextComponent.CreateReader(context, fullstyle);

            if (null != this._reader)
            {
                this.ContinueLayout = true;
                this.DoLayoutText();
            }

            this.Context.PerformanceMonitor.End(PerformanceMonitorType.Text_Layout);
        }
コード例 #12
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);
        }
コード例 #13
0
        public void CreateTextOptionsTest()
        {
            Style target = new Style();
            PDFTextRenderOptions actual = target.CreateTextOptions();

            Assert.IsNull(actual.Background);
            Assert.IsNull(actual.FillBrush);

            //Default value unit for first line inset and word spacing is Zero.
            Assert.IsTrue(actual.FirstLineInset.HasValue);
            Assert.AreEqual(PDFUnit.Zero, actual.FirstLineInset.Value);

            Assert.IsFalse(actual.WordSpacing.HasValue);
            Assert.IsNull(actual.Font, "Font is not null");
            Assert.IsNull(actual.Stroke);
            Assert.IsFalse(actual.Leading.HasValue);

            Assert.IsFalse(actual.WrapText.HasValue);

            //set the specific values

            target = new Style();

            target.Background.Color     = PDFColors.Lime;
            target.Background.FillStyle = Scryber.Drawing.FillType.Solid;

            target.Fill.Color = PDFColors.Navy;
            target.Fill.Style = Scryber.Drawing.FillType.Solid;

            target.Stroke.Color     = PDFColors.Purple;
            target.Stroke.Width     = 2;
            target.Stroke.LineStyle = LineType.Solid;


            target.Font.FontSize   = 36;
            target.Font.FontFamily = (PDFFontSelector)"Bauhaus 92";


            target.Text.WrapText    = Text.WordWrap.NoWrap;
            target.Text.WordSpacing = 1.0F;


            //validate against settings
            actual = target.CreateTextOptions();

            Assert.IsInstanceOfType(actual.Background, typeof(PDFSolidBrush));
            Assert.AreEqual(PDFColors.Lime, ((PDFSolidBrush)actual.Background).Color);

            Assert.IsInstanceOfType(actual.FillBrush, typeof(PDFSolidBrush));
            Assert.AreEqual(PDFColors.Navy, ((PDFSolidBrush)actual.FillBrush).Color);

            Assert.IsInstanceOfType(actual.Stroke, typeof(PDFSolidPen));
            Assert.AreEqual(PDFColors.Purple, ((PDFSolidPen)actual.Stroke).Color);
            Assert.AreEqual((PDFUnit)2, actual.Stroke.Width);

            Assert.IsInstanceOfType(actual.Font, typeof(PDFFont));
            Assert.AreEqual((PDFFontSelector)"Bauhaus 92", actual.Font.Selector);
            Assert.AreEqual((PDFUnit)36, actual.Font.Size);


            Assert.IsTrue(actual.WordSpacing.HasValue);
            Assert.AreEqual((PDFUnit)1.0, actual.WordSpacing.Value);

            Assert.IsTrue(actual.WrapText.HasValue);
            Assert.AreEqual(Text.WordWrap.NoWrap, actual.WrapText.Value);
        }
コード例 #14
0
        //
        // overrides
        //

        #region protected override void DoPushComponentLayout(PDFLayoutContext context, int pageIndex, PDFUnit xoffset, PDFUnit yoffset)

        /// <summary>
        /// Overrides the default behaviour to push any arrangements for the child item of this region
        /// </summary>
        /// <param name="context"></param>
        protected override void DoPushComponentLayout(PDFLayoutContext context, int pageIndex, PDFUnit xoffset, PDFUnit yoffset)
        {
            bool logdebug = context.ShouldLogDebug;

            if (logdebug)
            {
                context.TraceLog.Begin(TraceLevel.Debug, "Layout Region", "Pushing the component layout for the region " + this.ToString());
            }


            if (!this.IsClosed)
            {
                if (logdebug)
                {
                    context.TraceLog.Add(TraceLevel.Debug, PDFLayoutItem.LOG_CATEGORY, "Closing the region " + this.ToString() + " before pushing the layout");
                }
                this.Close();
            }

            if (this._contents == null || this.Contents.Count == 0)
            {
                if (logdebug)
                {
                    context.TraceLog.Add(TraceLevel.Debug, PDFLayoutItem.LOG_CATEGORY, "The region " + this.ToString() + " is empty. Exiting the push component early.");
                }
                return;
            }

            bool applyAlignments = this.ShouldApplyAlignment();

            if (applyAlignments)
            {
                VerticalAlignment v = this.VAlignment;
                if (v != VerticalAlignment.Top)
                {
                    this.EnsureCorrectHeight();
                    if (logdebug)
                    {
                        context.TraceLog.Add(TraceLevel.Debug, PDFLayoutItem.LOG_CATEGORY, "Adjusting the vertical offset of the region " + this.ToString() + " as it is not top aligned");
                    }

                    PDFUnit space = this.AvailableHeight;

                    if (v == VerticalAlignment.Middle)
                    {
                        space = space / 2;
                    }
                    yoffset += space;
                }
            }


            HorizontalAlignment h = this.HAlignment;

            PDFTextRenderOptions       options = (this.Parent as PDFLayoutBlock).FullStyle.CreateTextOptions();
            List <PDFTextRunCharacter> cache   = new List <PDFTextRunCharacter>();
            bool lastwasapplied = false;

            foreach (PDFLayoutItem item in this.Contents)
            {
                PDFUnit itemXOffset = xoffset;

                ///Individually calculate each lines horizontal offset
                if (applyAlignments && h != HorizontalAlignment.Left)
                {
                    PDFUnit space = this.TotalBounds.Width - item.Width;

                    if (h == HorizontalAlignment.Justified)
                    {
                        if (item is PDFLayoutLine)
                        {
                            PDFLayoutLine line = item as PDFLayoutLine;
                            if (logdebug)
                            {
                                context.TraceLog.Add(TraceLevel.Debug, PDFLayoutItem.LOG_CATEGORY, "Justifying the textual content of the line " + line.LineIndex);
                            }

                            bool didjustify = line.JustifyContent(this.TotalBounds.Width, item.Width, space, false, cache, ref options);

                            if (!didjustify && lastwasapplied && null != options && !(options.WordSpacing.HasValue || options.CharacterSpacing.HasValue))
                            {
                                line.ResetJustifySpacing(options);
                            }

                            lastwasapplied = didjustify;
                        }
                        space = 0; // reset space to zero as already accounted for.
                    }
                    else if (h == HorizontalAlignment.Center)
                    {
                        space = space / 2;
                    }

                    itemXOffset = itemXOffset + space;
                }

                item.PushComponentLayout(context, pageIndex, itemXOffset, yoffset);
            }

            if (logdebug)
            {
                context.TraceLog.End(TraceLevel.Debug, "Layout Region", "Pushed all the component layouts for the region " + this.ToString());
            }
        }
コード例 #15
0
        //
        // ctor
        //

        #region public PDFTextRunNewLine(bool isHardReturn, PDFLayoutLine line, IPDFComponent owner)

        /// <summary>
        /// Creates a new line text run.
        /// </summary>
        /// <param name="isHardReturn"></param>
        /// <param name="line"></param>
        /// <param name="owner"></param>
        public PDFTextRunNewLine(bool isHardReturn, PDFLayoutLine line, PDFTextRenderOptions opts, IPDFComponent owner)
            : base(line, owner)
        {
            this.IsHardReturn = isHardReturn;
            this.TextOptions  = opts;
        }
コード例 #16
0
        /// <summary>
        /// Measures a single line of text (no wrapping) and returns the size required,
        /// and the number of characters fitted into that line. Uses the current font and size.
        /// </summary>
        /// <param name="chars"></param>
        /// <param name="startIndex"></param>
        /// <param name="available"></param>
        /// <param name="options"></param>
        /// <param name="charsfitted"></param>
        /// <returns></returns>
        /// <remarks>Uses the TTFFontFile if available, otherwise will default to using the GDI+ measure,
        /// which is slower but supports postscript fonts</remarks>
        public PDFSize MeasureString(string chars, int startIndex, PDFSize available, PDFTextRenderOptions options, out int charsfitted)
        {
            PDFFontResource frsc  = this.CurrentFontResource;
            PDFUnit         fsize = this.CurrentFont.Size;

            if (null == frsc)
            {
                throw new InvalidOperationException("Current font has not be set on the graphics class, so strings cannot be measured");
            }

            PDFFontDefinition defn = frsc.Definition;
            PDFSize           measured;

            if (defn.CanMeasureStrings)
            {
                bool trimtoword = true;
                if (options.WrapText.HasValue)
                {
                    if (options.WrapText == WordWrap.NoWrap)
                    {
                        available.Width = new PDFUnit(int.MaxValue, PageUnits.Points);
                    }
                    else if (options.WrapText == WordWrap.Character)
                    {
                        trimtoword = false;
                    }
                }
                bool vertical = false; // Not currently supported.

                //inspect the spacing values - if any are set then we must use them in the calculations
                bool   complexSpacing = false;
                double?wordSpace      = null;
                double charSpace      = Scryber.OpenType.TTFFile.NoCharacterSpace;
                double hScale         = Scryber.OpenType.TTFFile.NoHorizontalScale;

                if (options.WordSpacing.HasValue)
                {
                    complexSpacing = true;
                    wordSpace      = options.WordSpacing.Value.PointsValue;
                }
                if (options.CharacterSpacing.HasValue)
                {
                    complexSpacing = true;
                    charSpace      = options.CharacterSpacing.Value.PointsValue;
                }
                if (options.CharacterHScale.HasValue)
                {
                    complexSpacing = true;
                    hScale         = options.CharacterHScale.Value;
                }
                if (complexSpacing)
                {
                    //TODO: Check if we can do this on the widths rather than the ttfile.
                    measured = defn.MeasureStringWidth(chars, startIndex, fsize.PointsValue, available.Width.PointsValue, wordSpace, charSpace, hScale, vertical, trimtoword, out charsfitted);
                }
                else
                {
                    //TODO: Check if we can do this on the widths rather than the ttfile.
                    measured = defn.MeasureStringWidth(chars, startIndex, fsize.PointsValue, available.Width.PointsValue, trimtoword, out charsfitted);
                }

                if (charsfitted > 0)
                {
                    this.RegisterStringUse(chars, startIndex, charsfitted);
                }
            }
            else
            {
                throw new NotSupportedException("The font definition cannot measure strings");

                //if (startIndex > 0)
                //   chars = chars.Substring(startIndex);
                //measured = this.MeasureGraphicsString(chars, available, options.WrapText.HasValue ? options.WrapText.Value : WordWrap.Auto, out charsfitted);
            }

            return(measured);
        }
コード例 #17
0
        //
        // ctor
        //


        public PDFTextRunBegin(PDFTextRenderOptions renderopts, PDFLayoutLine line, IPDFComponent owner)
            : base(line, owner)
        {
            this.TextRenderOptions = renderopts;
            this.Lines.Add(line);
        }
コード例 #18
0
        public PDFSize GetRequiredSizeForLayout(PDFSize available, PDFLayoutContext context, Style appliedstyle)
        {
            PDFPositionOptions   pos  = appliedstyle.CreatePostionOptions();
            PDFTextRenderOptions opts = appliedstyle.CreateTextOptions();
            PDFImageXObject      xobj = this.GetImageObject(context, appliedstyle);
            PDFSize naturalSize       = xobj.GetImageSize();

            PDFUnit h;
            PDFUnit w;

            if (pos.Height.HasValue && pos.Width.HasValue)
            {
                w = pos.Width.Value;
                h = pos.Height.Value;
            }
            else if (pos.Width.HasValue)
            {
                w = pos.Width.Value;
                h = naturalSize.Height * (pos.Width.Value.PointsValue / naturalSize.Width.PointsValue);
            }
            else if (pos.Height.HasValue)
            {
                h = pos.Height.Value;
                w = naturalSize.Width * (pos.Height.Value.PointsValue / naturalSize.Height.PointsValue);
            }
            else if (pos.PositionMode == PositionMode.Inline)
            {
                //We dont have an explicit size
                //So set it to the line height.
                if (opts.Font != null && opts.Font.FontMetrics != null)
                {
                    h = opts.Font.FontMetrics.Ascent;
                }
                else
                {
                    h = opts.Font.Size * 0.75;
                }

                w = naturalSize.Width * (h.PointsValue / naturalSize.Height.PointsValue);
            }
            else //We are in a block on our own line
            {
                h = naturalSize.Height;
                w = naturalSize.Width;

                if (w > available.Width)
                {
                    w = available.Width;
                    h = naturalSize.Height * (available.Width.PointsValue / naturalSize.Width.PointsValue);
                    if (h < naturalSize.Height * this.MinimumScaleReduction)
                    {
                        //exceeded our maximum - so reverting back.
                        h = naturalSize.Height;
                        w = naturalSize.Width;
                    }
                }

                if (h > available.Height)
                {
                    h = available.Height;
                    w = naturalSize.Width * (available.Height.PointsValue / naturalSize.Height.PointsValue);

                    if (w < naturalSize.Width * this.MinimumScaleReduction)
                    {
                        h = naturalSize.Height;
                        w = naturalSize.Width;
                    }
                }
            }


            return(new PDFSize(w, h));
        }