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)); } }
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); }
//------------------------------------------------------ // // 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)); } } }
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; } }
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); } } }
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); }