Ejemplo n.º 1
0
        /// <summary>
        /// Get the Geometry of the Stroke
        /// </summary>
        /// <param name="drawingAttributes"></param>
        /// <returns></returns>
        public Geometry GetGeometry(DrawingAttributes drawingAttributes)
        {
            if (drawingAttributes == null)
            {
                throw new ArgumentNullException("drawingAttributes");
            }

            bool geometricallyEqual = DrawingAttributes.GeometricallyEqual(drawingAttributes, this.DrawingAttributes);

            // need to recalculate the PathGemetry if the DA passed in is "geometrically" different from
            // this DA, or if the cached PathGeometry is dirty.
            if (false == geometricallyEqual || (true == geometricallyEqual && null == _cachedGeometry))
            {
                //Recalculate _pathGeometry;
                StrokeNodeIterator iterator = StrokeNodeIterator.GetIterator(this, drawingAttributes);
                Geometry           geometry;
                Rect bounds;
                StrokeRenderer.CalcGeometryAndBounds(iterator,
                                                     drawingAttributes,
#if DEBUG_RENDERING_FEEDBACK
                                                     null, 0d, false,
#endif
                                                     true, //calc bounds
                                                     out geometry,
                                                     out bounds);

                // return the calculated value directly. We cannot cache the result since the DA passed in
                // is "geometrically" different from this.DrawingAttributes.
                if (false == geometricallyEqual)
                {
                    return(geometry);
                }

                // Cache the value and set _isPathGeometryDirty to false;
                SetGeometry(geometry);
                SetBounds(bounds);

                return(geometry);
            }

            // return a ref to our _cachedGeometry
            System.Diagnostics.Debug.Assert(_cachedGeometry != null && _cachedGeometry.IsFrozen);
            return(_cachedGeometry);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The core functionality to draw a stroke. The function can be called from the following code paths.
        ///     i) From StrokeVisual.OnRender
        ///         a. Highlighter strokes have been grouped and the correct opacity has been set on the container visual.
        ///         b. For a highlighter stroke with color.A != 255, the DA passed in is a copy with color.A set to 255.
        ///         c. _drawAsHollow can be true, i.e., Selected stroke is drawn as hollow
        ///     ii) From StrokeCollection.Draw.
        ///         a. Highlighter strokes have been grouped and the correct opacity has been pushed.
        ///         b. For a highlighter stroke with color.A != 255, the DA passed in is a copy with color.A set to 255.
        ///         c. _drawAsHollow is always false, i.e., Selected stroke is not drawn as hollow
        ///     iii) From Stroke.Draw
        ///         a. The correct opacity has been pushed for a highlighter stroke
        ///         b. For a highlighter stroke with color.A != 255, the DA passed in is a copy with color.A set to 255.
        ///         c. _drawAsHollow is always false, i.e., Selected stroke is not drawn as hollow
        /// We need to document the following:
        /// 1) our default implementation so developers can see what we've done here -
        ///    including how we handle IsHollow
        /// 2) the fact that opacity has already been set up correctly for the call.
        /// 3) that developers should not call base.DrawCore if they override this
        /// </summary>
        /// <param name="drawingContext">DrawingContext to draw on</param>
        /// <param name="drawingAttributes">DrawingAttributes to draw with</param>
        protected virtual void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes)
        {
            if (null == drawingContext)
            {
                throw new System.ArgumentNullException("drawingContext");
            }

            if (null == drawingAttributes)
            {
                throw new System.ArgumentNullException("drawingAttributes");
            }

            if (_drawAsHollow == true)
            {
                // Draw as hollow. Our profiler result shows that the two-pass-rendering approach is about 5 times
                // faster that using GetOutlinePathGeometry.
                // also, the minimum display size for selected ink is our default width / height

                Matrix            innerTransform, outerTransform;
                DrawingAttributes selectedDA = drawingAttributes.Clone();
                selectedDA.Height = Math.Max(selectedDA.Height, DrawingAttributes.DefaultHeight);
                selectedDA.Width  = Math.Max(selectedDA.Width, DrawingAttributes.DefaultWidth);
                CalcHollowTransforms(selectedDA, out innerTransform, out outerTransform);

                // First pass drawing. Use drawingAttributes.Color to create a solid color brush. The stroke will be drawn as
                // 1 avalon-unit higher and wider (HollowLineSize = 1.0f)
                selectedDA.StylusTipTransform = outerTransform;
                SolidColorBrush brush = new SolidColorBrush(drawingAttributes.Color);
                brush.Freeze();
                drawingContext.DrawGeometry(brush, null, GetGeometry(selectedDA));

                //Second pass drawing with a white color brush. The stroke will be drawn as
                // 1 avalon-unit shorter and narrower (HollowLineSize = 1.0f) if the actual-width/height (considering StylusTipTransform)
                // is larger than HollowLineSize. Otherwise the same size stroke is drawn.
                selectedDA.StylusTipTransform = innerTransform;
                drawingContext.DrawGeometry(Brushes.White, null, GetGeometry(selectedDA));
            }
            else
            {
#if DEBUG_RENDERING_FEEDBACK
                //render debug feedback?
                Guid guid = new Guid("52053C24-CBDD-4547-AAA1-DEFEBF7FD1E1");
                if (this.ContainsPropertyData(guid))
                {
                    double thickness = (double)this.GetPropertyData(guid);

                    //first, draw the outline of the stroke
                    drawingContext.DrawGeometry(null,
                                                new Pen(Brushes.Black, thickness),
                                                GetGeometry());

                    Geometry g2;
                    Rect     b2;
                    //next, overlay the connecting quad points
                    StrokeRenderer.CalcGeometryAndBounds(StrokeNodeIterator.GetIterator(this, drawingAttributes),
                                                         drawingAttributes,
                                                         drawingContext, thickness, true,
                                                         true, //calc bounds
                                                         out g2,
                                                         out b2);
                }
                else
                {
#endif
                SolidColorBrush brush = new SolidColorBrush(drawingAttributes.Color);
                brush.Freeze();
                drawingContext.DrawGeometry(brush, null, GetGeometry(drawingAttributes));
#if DEBUG_RENDERING_FEEDBACK
            }
#endif
            }
        }