public void AddArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArg, XSweepDirection sweepDirection)
        {
            List <XPoint> points = GeometryHelper.BezierCurveFromArc(point1, point2, size, rotationAngle, isLargeArg,
                                                                     sweepDirection == XSweepDirection.Clockwise, PathStart.MoveTo1st);
            int count = points.Count;

            Debug.Assert((count + 2) % 3 == 0);

            MoveOrLineTo(points[0].X, points[0].Y);
            for (int idx = 1; idx < count; idx += 3)
            {
                BezierTo(points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y, false);
            }
        }
Beispiel #2
0
 /// <summary>
 /// Initializes a new instance of the XRect class.
 /// </summary>
 public XRect(XPoint location, XSize size)
 {
     if (size.IsEmpty)
     {
         this = s_empty;
     }
     else
     {
         _x      = location.X;
         _y      = location.Y;
         _width  = size.Width;
         _height = size.Height;
     }
 }
        /// <summary>
        /// Measure string directly from font data.
        /// </summary>
        public static XSize MeasureString(string text, XFont font, XStringFormat stringFormat)
        {
            XSize size = new XSize();

            OpenTypeDescriptor descriptor = FontDescriptorCache.GetOrCreateDescriptorFor(font) as OpenTypeDescriptor;

            if (descriptor != null)
            {
                // Height is the sum of ascender and descender.
                size.Height = (descriptor.Ascender + descriptor.Descender) * font.Size / font.UnitsPerEm;
                Debug.Assert(descriptor.Ascender > 0);

                bool symbol = descriptor.FontFace.cmap.symbol;
                int  length = text.Length;
                int  width  = 0;
                for (int idx = 0; idx < length; idx++)
                {
                    char ch = text[idx];
                    // HACK: Unclear what to do here.
                    if (ch < 32)
                    {
                        continue;
                    }

                    if (symbol)
                    {
                        // Remap ch for symbol fonts.
                        ch = (char)(ch | (descriptor.FontFace.os2.usFirstCharIndex & 0xFF00));  // @@@ refactor
                        // Used | instead of + because of: http://PdfSharpCore.codeplex.com/workitem/15954
                    }
                    int glyphIndex = descriptor.CharCodeToGlyphIndex(ch);
                    width += descriptor.GlyphIndexToWidth(glyphIndex);
                }
                // What? size.Width = width * font.Size * (font.Italic ? 1 : 1) / descriptor.UnitsPerEm;
                size.Width = width * font.Size / descriptor.UnitsPerEm;

                // Adjust bold simulation.
                if ((font.GlyphTypeface.StyleSimulations & XStyleSimulations.BoldSimulation) == XStyleSimulations.BoldSimulation)
                {
                    // Add 2% of the em-size for each character.
                    // Unsure how to deal with white space. Currently count as regular character.
                    size.Width += length * font.Size * Const.BoldEmphasis;
                }
            }
            Debug.Assert(descriptor != null, "No OpenTypeDescriptor.");
            return(size);
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="XForm"/> class that represents a page of a PDF document.
        /// </summary>
        /// <param name="document">The PDF document.</param>
        /// <param name="size">The size of the page.</param>
        public XForm(PdfDocument document, XSize size)
            : this(document, new XRect(0, 0, size.Width, size.Height))
        {
            ////if (size.width < 1 || size.height < 1)
            ////  throw new ArgumentNullException("size", "The size of the XPdfForm is to small.");
            ////// I must tie the XPdfForm to a document immediately, because otherwise I would have no place where
            ////// to store the resources.
            ////if (document == null)
            ////  throw new ArgumentNullException("document", "An XPdfForm template must be associated with a document.");

            ////_formState = FormState.Created;
            ////_document = document;
            ////pdfForm = new PdfFormXObject(document, this);
            ////templateSize = size;
            ////PdfRectangle rect = new PdfRectangle(new XPoint(), size);
            ////pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, rect);
        }
        /// <summary>
        /// Parses the size from a string.
        /// </summary>
        public static XSize Parse(string source)
        {
            XSize           empty;
            CultureInfo     cultureInfo = CultureInfo.InvariantCulture;
            TokenizerHelper helper      = new TokenizerHelper(source, cultureInfo);
            string          str         = helper.NextTokenRequired();

            if (str == "Empty")
            {
                empty = Empty;
            }
            else
            {
                empty = new XSize(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
            }
            helper.LastTokenRequired();
            return(empty);
        }
Beispiel #6
0
 /// <summary>
 /// Returns the rectangle that results from expanding the specified rectangle by the specified Size, in all directions.
 /// </summary>
 public static XRect Inflate(XRect rect, XSize size)
 {
     rect.Inflate(size.Width, size.Height);
     return(rect);
 }
Beispiel #7
0
 /// <summary>
 /// Expands the rectangle by using the specified Size, in all directions.
 /// </summary>
 public void Inflate(XSize size)
 {
     Inflate(size.Width, size.Height);
 }
Beispiel #8
0
        /// <summary>
        /// Creates between 1 and 5 Béziers curves from parameters specified like in WPF.
        /// </summary>
        public static List <XPoint> BezierCurveFromArc(XPoint point1, XPoint point2, XSize size,
                                                       double rotationAngle, bool isLargeArc, bool clockwise, PathStart pathStart)
        {
            // See also http://www.charlespetzold.com/blog/blog.xml from January 2, 2008:
            // http://www.charlespetzold.com/blog/2008/01/Mathematics-of-ArcSegment.html
            double δx = size.Width;
            double δy = size.Height;

            Debug.Assert(δx * δy > 0);
            double factor             = δy / δx;
            bool   isCounterclockwise = !clockwise;

            // Adjust for different radii and rotation angle.
            XMatrix matrix = new XMatrix();

            matrix.RotateAppend(-rotationAngle);
            matrix.ScaleAppend(δy / δx, 1);
            XPoint pt1 = matrix.Transform(point1);
            XPoint pt2 = matrix.Transform(point2);

            // Get info about chord that connects both points.
            XPoint  midPoint  = new XPoint((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2);
            XVector vect      = pt2 - pt1;
            double  halfChord = vect.Length / 2;

            // Get vector from chord to center.
            XVector vectRotated;

            // (comparing two Booleans here!)
            if (isLargeArc == isCounterclockwise)
            {
                vectRotated = new XVector(-vect.Y, vect.X);
            }
            else
            {
                vectRotated = new XVector(vect.Y, -vect.X);
            }

            vectRotated.Normalize();

            // Distance from chord to center.
            double centerDistance = Math.Sqrt(δy * δy - halfChord * halfChord);

            if (double.IsNaN(centerDistance))
            {
                centerDistance = 0;
            }

            // Calculate center point.
            XPoint center = midPoint + centerDistance * vectRotated;

            // Get angles from center to the two points.
            double α = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X);
            double β = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X);

            // (another comparison of two Booleans!)
            if (isLargeArc == (Math.Abs(β - α) < Math.PI))
            {
                if (α < β)
                {
                    α += 2 * Math.PI;
                }
                else
                {
                    β += 2 * Math.PI;
                }
            }

            // Invert matrix for final point calculation.
            matrix.Invert();
            double sweepAngle = β - α;

            // Let the algorithm of GDI+ DrawArc to Bézier curves do the rest of the job
            return(BezierCurveFromArc(center.X - δx * factor, center.Y - δy, 2 * δx * factor, 2 * δy,
                                      α / Calc.Deg2Rad, sweepAngle / Calc.Deg2Rad, pathStart, ref matrix));
        }
 static XSize()
 {
     s_empty = CreateEmptySize();
 }
Beispiel #10
0
 /// <summary>
 /// Indicates whether this instance and a specified size are equal.
 /// </summary>
 public bool Equals(XSize value)
 {
     return(Equals(this, value));
 }