Esempio n. 1
0
        internal unsafe bool ContainsInternal(Pen pen, Point hitPoint, double tolerance, ToleranceType type,
                                              Point *pPoints, uint pointCount, byte *pTypes, uint typeCount)
        {
            bool contains = false;

            MilMatrix3x2D matrix = CompositionResourceManager.TransformToMilMatrix3x2D(Transform);

            MIL_PEN_DATA penData;

            double[] dashArray = null;

            if (pen != null)
            {
                pen.GetBasicPenData(&penData, out dashArray);
            }

            fixed(double *dashArrayFixed = dashArray)
            {
                int hr = MilCoreApi.MilUtility_PolygonHitTest(
                    &matrix,
                    (pen == null) ? null : &penData,
                    dashArrayFixed,
                    pPoints,
                    pTypes,
                    pointCount,
                    typeCount,
                    tolerance,
                    type == ToleranceType.Relative,
                    &hitPoint,
                    out contains);

                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 is never hittable.
                    contains = false;
                }
                else
                {
                    HRESULT.Check(hr);
                }
            }

            return(contains);
        }
Esempio n. 2
0
        internal override void AddToFigure(
            Matrix matrix,          // The transformation matrid
            PathFigure figure,      // The figure to add to
            ref Point current)      // In: Segment start point, Out: Segment endpoint, neither transformed
        {
            Point endPoint = Point;

            if (matrix.IsIdentity)
            {
                figure.Segments.Add(this);
            }
            else
            {
                // The arc segment is approximated by up to 4 Bezier segments
                unsafe
                {
                    int           count;
                    Point *       points   = stackalloc Point[12];
                    Size          size     = Size;
                    Double        rotation = RotationAngle;
                    MilMatrix3x2D mat3X2   = CompositionResourceManager.MatrixToMilMatrix3x2D(ref matrix);

                    Composition.MilCoreApi.MilUtility_ArcToBezier(
                        current,    // =start point
                        size,
                        rotation,
                        IsLargeArc,
                        SweepDirection,
                        endPoint,
                        &mat3X2,
                        points,
                        out count); // = number of Bezier segments

                    Invariant.Assert(count <= 4);

                    // To ensure no buffer overflows
                    count = Math.Min(count, 4);

                    bool isStroked    = IsStroked;
                    bool isSmoothJoin = IsSmoothJoin;

                    // Add the segments
                    if (count > 0)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            figure.Segments.Add(new BezierSegment(
                                                    points[3 * i],
                                                    points[3 * i + 1],
                                                    points[3 * i + 2],
                                                    isStroked,
                                                    (i < count - 1) || isSmoothJoin)); // Smooth join between arc pieces
                        }
                    }
                    else if (count == 0)
                    {
                        figure.Segments.Add(new LineSegment(points[0], isStroked, isSmoothJoin));
                    }
                }

                // Update the last point
                current = endPoint;
            }
        }
Esempio n. 3
0
        internal static MilRectD GetPathBoundsAsRB(
            PathGeometryData pathData,
            Pen pen,
            Matrix worldMatrix,
            double tolerance,
            ToleranceType type,
            bool skipHollows)
        {
            // This method can't handle the empty geometry case, as it's impossible for us to
            // return Rect.Empty. Callers should do their own check.
            Debug.Assert(!pathData.IsEmpty());

            unsafe
            {
                MIL_PEN_DATA penData;
                double[]     dashArray = null;

                // If we have a pen, populate the CMD struct
                if (pen != null)
                {
                    pen.GetBasicPenData(&penData, out dashArray);
                }

                MilMatrix3x2D worldMatrix3X2 = CompositionResourceManager.MatrixToMilMatrix3x2D(ref worldMatrix);

                fixed(byte *pbPathData = pathData.SerializedData)
                {
                    MilRectD bounds;

                    Debug.Assert(pbPathData != (byte *)0);

                    fixed(double *pDashArray = dashArray)
                    {
                        int hr = UnsafeNativeMethods.MilCoreApi.MilUtility_PathGeometryBounds(
                            (pen == null) ? null : &penData,
                            pDashArray,
                            &worldMatrix3X2,
                            pathData.FillRule,
                            pbPathData,
                            pathData.Size,
                            &pathData.Matrix,
                            tolerance,
                            type == ToleranceType.Relative,
                            skipHollows,
                            &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
                            // (NaN will get transformed into Rect.Empty higher up).

                            bounds = MilRectD.NaN;
                        }
                        else
                        {
                            HRESULT.Check(hr);
                        }
                    }

                    return(bounds);
                }
            }
        }
Esempio n. 4
0
        internal static PathGeometry InternalCombine(
            Geometry geometry1,
            Geometry geometry2,
            GeometryCombineMode mode,
            Transform transform,
            double tolerance,
            ToleranceType type)
        {
            PathGeometry resultGeometry = null;

            unsafe
            {
                MilMatrix3x2D matrix = CompositionResourceManager.TransformToMilMatrix3x2D(transform);

                PathGeometryData data1 = geometry1.GetPathGeometryData();
                PathGeometryData data2 = geometry2.GetPathGeometryData();

                fixed(byte *pPathData1 = data1.SerializedData)
                {
                    Debug.Assert(pPathData1 != (byte *)0);

                    fixed(byte *pPathData2 = data2.SerializedData)
                    {
                        Debug.Assert(pPathData2 != (byte *)0);

                        FillRule fillRule = FillRule.Nonzero;

                        FigureList list = new FigureList();
                        int        hr   = UnsafeNativeMethods.MilCoreApi.MilUtility_PathGeometryCombine(
                            &matrix,
                            &data1.Matrix,
                            data1.FillRule,
                            pPathData1,
                            data1.Size,
                            &data2.Matrix,
                            data2.FillRule,
                            pPathData2,
                            data2.Size,
                            tolerance,
                            type == ToleranceType.Relative,
                            new AddFigureToListDelegate(list.AddFigureToList),
                            mode,
                            out fillRule);

                        if (hr == (int)MILErrors.WGXERR_BADNUMBER)
                        {
                            // When we encounter NaNs in the renderer, we absorb the error and draw
                            // nothing. To be consistent, we return an empty geometry.
                            resultGeometry = new PathGeometry();
                        }
                        else
                        {
                            HRESULT.Check(hr);

                            resultGeometry = new PathGeometry(list.Figures, fillRule, null);
                        }
                    }
                }
            }

            return(resultGeometry);
        }
Esempio n. 5
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);
        }