Exemple #1
0
        protected override void UpdateResourceCore(DUCE.Channel channel)
        {
            Debug.Assert(_duceResource.IsOnChannel(channel));
            DependencyObject dobj = ((DependencyObject)_dependencyObject.Target);

            // The dependency object was GCed, nothing to do here
            if (dobj == null)
            {
                return;
            }

            Matrix tempValue = (Matrix)dobj.GetValue(_dependencyProperty);

            DUCE.MILCMD_MATRIXRESOURCE data;
            data.Type   = MILCMD.MilCmdMatrixResource;
            data.Handle = _duceResource.GetHandle(channel);
            data.Value  = CompositionResourceManager.MatrixToMilMatrix3x2D(tempValue);

            unsafe
            {
                channel.SendCommand(
                    (byte *)&data,
                    sizeof(DUCE.MILCMD_MATRIXRESOURCE));
            }
        }
Exemple #2
0
        private static PathGeometryData MakeEmptyPathGeometryData()
        {
            PathGeometryData data = new PathGeometryData();

            data.FillRule = FillRule.EvenOdd;
            data.Matrix   = CompositionResourceManager.MatrixToMilMatrix3x2D(Matrix.Identity);

            unsafe
            {
                int size = sizeof(MIL_PATHGEOMETRY);

                data.SerializedData = new byte[size];

                fixed(byte *pbData = data.SerializedData)
                {
                    MIL_PATHGEOMETRY *pPathGeometry = (MIL_PATHGEOMETRY *)pbData;

                    // implicitly set pPathGeometry->Flags = 0;
                    pPathGeometry->FigureCount = 0;
                    pPathGeometry->Size        = (UInt32)size;
                }
            }

            return(data);
        }
Exemple #3
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal override void UpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
        {
            // If we're told we can skip the channel check, then we must be on channel
            Debug.Assert(!skipOnChannelCheck || _duceResource.IsOnChannel(channel));

            if (skipOnChannelCheck || _duceResource.IsOnChannel(channel))
            {
                base.UpdateResource(channel, skipOnChannelCheck);

                // Obtain handles for animated properties
                DUCE.ResourceHandle hMatrixAnimations = GetAnimationResourceHandle(MatrixProperty, channel);

                // Pack & send command packet
                DUCE.MILCMD_MATRIXTRANSFORM data;
                unsafe
                {
                    data.Type   = MILCMD.MilCmdMatrixTransform;
                    data.Handle = _duceResource.GetHandle(channel);
                    if (hMatrixAnimations.IsNull)
                    {
                        data.Matrix = CompositionResourceManager.MatrixToMilMatrix3x2D(Matrix);
                    }
                    data.hMatrixAnimations = hMatrixAnimations;

                    // Send packed command structure
                    channel.SendCommand(
                        (byte *)&data,
                        sizeof(DUCE.MILCMD_MATRIXTRANSFORM));
                }
            }
        }
Exemple #4
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;
            }
        }
Exemple #5
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);
                }
            }
        }
Exemple #6
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);
        }