/// <summary>
        ///     DrawEllipse -
        ///     Draw an ellipse with the provided Brush and/or Pen.
        ///     If both the Brush and Pen are null this call is a no-op.
        /// </summary>
        /// <param name="brush">
        ///     The Brush with which to fill the ellipse.
        ///     This is optional, and can be null, in which case no fill is performed.
        /// </param>
        /// <param name="pen">
        ///     The Pen with which to stroke the ellipse.
        ///     This is optional, and can be null, in which case no stroke is performed.
        /// </param>
        /// <param name="center">
        ///     The center of the ellipse to fill and/or stroke.
        /// </param>
        /// <param name="radiusX">
        ///     The radius in the X dimension of the ellipse.
        ///     The absolute value of the radius provided will be used.
        /// </param>
        /// <param name="radiusY">
        ///     The radius in the Y dimension of the ellipse.
        ///     The absolute value of the radius provided will be used.
        /// </param>
        public override void DrawEllipse(
            Brush brush,
            Pen pen,
            Point center,
            Double radiusX,
            Double radiusY)
        {
            if ((brush != null) || Pen.ContributesToBounds(pen))
            {
                // _bounds is always in "world" space
                // So, we need to transform the geometry to world to bound it
                Rect geometryBounds = EllipseGeometry.GetBoundsHelper(
                    pen,
                    _transform, // world transform
                    center,
                    radiusX,
                    radiusY,
                    Matrix.Identity, // geometry transform
                    Geometry.StandardFlatteningTolerance,
                    ToleranceType.Absolute
                    );

                AddTransformedBounds(ref geometryBounds);
            }
        }
Exemplo n.º 2
0
        internal static Rect GetBoundsHelper(Pen pen, Matrix worldMatrix, Rect rect, double radiusX, double radiusY,
                                             Matrix geometryMatrix, double tolerance, ToleranceType type)
        {
            Rect boundingRect;

            if (rect.IsEmpty)
            {
                boundingRect = Rect.Empty;
            }
            else if ((pen == null || pen.DoesNotContainGaps) &&
                     geometryMatrix.IsIdentity && worldMatrix.IsIdentity)
            {
                double strokeThickness = 0.0;

                boundingRect = rect;

                if (Pen.ContributesToBounds(pen))
                {
                    strokeThickness = Math.Abs(pen.Thickness);

                    boundingRect.X      -= 0.5 * strokeThickness;
                    boundingRect.Y      -= 0.5 * strokeThickness;
                    boundingRect.Width  += strokeThickness;
                    boundingRect.Height += strokeThickness;
                }
            }
            else
            {
                unsafe
                {
                    uint pointCount, segmentCount;
                    GetCounts(rect, radiusX, radiusY, out pointCount, out segmentCount);

                    // We've checked that rect isn't empty above
                    Invariant.Assert(pointCount != 0);

                    Point *pPoints = stackalloc Point[(int)pointCount];
                    RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY);

                    fixed(byte *pTypes = RectangleGeometry.GetTypeList(rect, radiusX, radiusY))
                    {
                        boundingRect = Geometry.GetBoundsHelper(
                            pen,
                            &worldMatrix,
                            pPoints,
                            pTypes,
                            pointCount,
                            segmentCount,
                            &geometryMatrix,
                            tolerance,
                            type,
                            false);  // skip hollows - meaningless here, this is never a hollow
                    }
                }
            }

            return(boundingRect);
        }
        /// <summary>
        ///     DrawGeometry -
        ///     Draw a Geometry with the provided Brush and/or Pen.
        ///     If both the Brush and Pen are null this call is a no-op.
        /// </summary>
        /// <param name="brush">
        ///     The Brush with which to fill the Geometry.
        ///     This is optional, and can be null, in which case no fill is performed.
        /// </param>
        /// <param name="pen">
        ///     The Pen with which to stroke the Geometry.
        ///     This is optional, and can be null, in which case no stroke is performed.
        /// </param>
        /// <param name="geometry"> The Geometry to fill and/or stroke. </param>
        public override void DrawGeometry(
            Brush brush,
            Pen pen,
            Geometry geometry)
        {
            if ((geometry != null) && ((brush != null) || Pen.ContributesToBounds(pen)))
            {
                // _bounds is always in "world" space
                // So, we need to transform the geometry to world to bound it
                Rect geometryBounds = geometry.GetBoundsInternal(pen, _transform);

                AddTransformedBounds(ref geometryBounds);
            }
        }
Exemplo n.º 4
0
        internal static Rect GetBoundsHelper(Pen pen, Matrix worldMatrix, Point center, double radiusX, double radiusY,
                                             Matrix geometryMatrix, double tolerance, ToleranceType type)
        {
            Rect rect;

            Debug.Assert(worldMatrix != null);
            Debug.Assert(geometryMatrix != null);

            if ((pen == null || pen.DoesNotContainGaps) &&
                worldMatrix.IsIdentity && geometryMatrix.IsIdentity)
            {
                double strokeThickness = 0.0;

                if (Pen.ContributesToBounds(pen))
                {
                    strokeThickness = Math.Abs(pen.Thickness);
                }

                rect = new Rect(
                    center.X - Math.Abs(radiusX) - 0.5 * strokeThickness,
                    center.Y - Math.Abs(radiusY) - 0.5 * strokeThickness,
                    2.0 * Math.Abs(radiusX) + strokeThickness,
                    2.0 * Math.Abs(radiusY) + strokeThickness);
            }
            else
            {
                unsafe
                {
                    Point *pPoints = stackalloc Point[(int)c_pointCount];
                    EllipseGeometry.GetPointList(pPoints, c_pointCount, center, radiusX, radiusY);

                    fixed(byte *pTypes = EllipseGeometry.s_roundedPathTypes)
                    {
                        rect = Geometry.GetBoundsHelper(
                            pen,
                            &worldMatrix,
                            pPoints,
                            pTypes,
                            c_pointCount,
                            c_segmentCount,
                            &geometryMatrix,
                            tolerance,
                            type,
                            false); // skip hollows - meaningless here, this is never a hollow
                    }
                }
            }

            return(rect);
        }
        /// <summary>
        ///     DrawLine -
        ///     Draws a line with the specified pen.
        ///     Note that this API does not accept a Brush, as there is no area to fill.
        /// </summary>
        /// <param name="pen"> The Pen with which to stroke the line. </param>
        /// <param name="point0"> The start Point for the line. </param>
        /// <param name="point1"> The end Point for the line. </param>
        public override void DrawLine(
            Pen pen,
            Point point0,
            Point point1)
        {
            if (Pen.ContributesToBounds(pen))
            {
                // _bounds is always in "world" space
                // So, we need to transform the geometry to world to bound it
                Rect geometryBounds = LineGeometry.GetBoundsHelper(
                    pen,
                    _transform, // world transform
                    point0,
                    point1,
                    Matrix.Identity, // geometry transform
                    Geometry.StandardFlatteningTolerance,
                    ToleranceType.Absolute
                    );

                AddTransformedBounds(ref geometryBounds);
            }
        }
        /// <summary>
        ///     DrawRectangle -
        ///     Draw a rectangle with the provided Brush and/or Pen.
        ///     If both the Brush and Pen are null this call is a no-op.
        /// </summary>
        /// <param name="brush">
        ///     The Brush with which to fill the rectangle.
        ///     This is optional, and can be null, in which case no fill is performed.
        /// </param>
        /// <param name="pen">
        ///     The Pen with which to stroke the rectangle.
        ///     This is optional, and can be null, in which case no stroke is performed.
        /// </param>
        /// <param name="rectangle"> The Rect to fill and/or stroke. </param>
        public override void DrawRectangle(
            Brush brush,
            Pen pen,
            Rect rectangle)
        {
            if ((brush != null) || Pen.ContributesToBounds(pen))
            {
                // _bounds is always in "world" space
                // So, we need to transform the geometry to world to bound it
                Rect geometryBounds = RectangleGeometry.GetBoundsHelper(
                    pen,
                    _transform, // world transform
                    rectangle,
                    0.0,
                    0.0,
                    Matrix.Identity, // geometry transform
                    Geometry.StandardFlatteningTolerance,
                    ToleranceType.Absolute
                    );

                AddTransformedBounds(ref geometryBounds);
            }
        }
Exemplo n.º 7
0
        internal unsafe static Rect GetBoundsHelper(
            Pen pen,
            Matrix *pWorldMatrix,
            Point *pPoints,
            byte *pTypes,
            uint pointCount,
            uint segmentCount,
            Matrix *pGeometryMatrix,
            double tolerance,
            ToleranceType type,
            bool fSkipHollows)
        {
            MIL_PEN_DATA penData;

            double[] dashArray = null;

            // If the pen contributes to the bounds, populate the CMD struct
            bool fPenContributesToBounds = Pen.ContributesToBounds(pen);

            if (fPenContributesToBounds)
            {
                pen.GetBasicPenData(&penData, out dashArray);
            }

            MilMatrix3x2D geometryMatrix;

            if (pGeometryMatrix != null)
            {
                geometryMatrix = CompositionResourceManager.MatrixToMilMatrix3x2D(ref (*pGeometryMatrix));
            }

            Debug.Assert(pWorldMatrix != null);
            MilMatrix3x2D worldMatrix =
                CompositionResourceManager.MatrixToMilMatrix3x2D(ref (*pWorldMatrix));

            Rect bounds;

            fixed(double *pDashArray = dashArray)
            {
                int hr = MilCoreApi.MilUtility_PolygonBounds(
                    &worldMatrix,
                    (fPenContributesToBounds) ? &penData : null,
                    (dashArray == null) ? null : pDashArray,
                    pPoints,
                    pTypes,
                    pointCount,
                    segmentCount,
                    (pGeometryMatrix == null) ? null : &geometryMatrix,
                    tolerance,
                    type == ToleranceType.Relative,
                    fSkipHollows,
                    &bounds
                    );

                if (hr == (int)MILErrors.WGXERR_BADNUMBER)
                {
                    // When we encounter NaNs in the renderer, we absorb the error and draw
                    // nothing. To be consistent, we report that the geometry has empty bounds.
                    bounds = Rect.Empty;
                }
                else
                {
                    HRESULT.Check(hr);
                }
            }

            return(bounds);
        }