Example #1
0
        private Pen ReducePen(Pen pen, Rect bounds)
        {
            if (PenProxy.IsNull(pen))
            {
                return(null);
            }

            Brush b = ReduceBrush(pen.Brush, bounds);

            if (b == null)
            {
                return(null);
            }

            if (!Object.ReferenceEquals(b, pen.Brush))
            {
                pen = pen.CloneCurrentValue();

                pen.Brush = b;
            }

            return(pen);
        }
Example #2
0
        void IProxyDrawingContext.DrawGeometry(BrushProxy brush, PenProxy pen, Geometry geometry, Geometry clip, Matrix brushTrans, ProxyDrawingFlags flags)
        {
            if ((brush != null) && (pen != null)) // Split fill & stroke into two
            {
                ((IProxyDrawingContext)(this)).DrawGeometry(brush, null, geometry, clip, brushTrans, flags);

                brush = null;
            }

            bool empty;

            clip = Utility.Intersect(_clip, Utility.TransformGeometry(clip, _transform), Matrix.Identity, out empty);

            if (empty)
            {
                return;
            }

            GeometryPrimitive geo = new GeometryPrimitive();

            // apply drawing flags to primitive
            if ((flags & ProxyDrawingFlags.PixelSnapBounds) != 0)
            {
                geo.PixelSnapBounds = true;
            }

            if (pen != null)
            {
                if (!brushTrans.IsIdentity)
                {
                    double scale;

                    bool uniform = Utility.HasUniformScale(brushTrans, out scale);

                    if (uniform)
                    {
                        geo.Pen = pen.Clone();
                        geo.Pen.Scale(scale);
                        geo.Pen.StrokeBrush.ApplyTransform(brushTrans);
                    }
                    else
                    {
                        // relative may not be good enough
                        geometry = Utility.InverseTransformGeometry(geometry, brushTrans);
                        geometry = geometry.GetWidenedPathGeometry(pen.GetPen(true), 0.0001, ToleranceType.Relative);
                        geometry = Utility.TransformGeometry(geometry, brushTrans);

                        brush = pen.StrokeBrush;
                        pen   = null;
                    }
                }
                else
                {
                    geo.Pen = pen.Clone();
                }
            }

            if (brush != null)
            {
                geo.Brush = brush.ApplyTransformCopy(brushTrans);
            }

            geo.Geometry  = geometry;
            geo.Clip      = clip;
            geo.Transform = _transform;

            geo.PushOpacity(_opacity, _opacityMask);
            _flattener.AddPrimitive(geo);
        }
Example #3
0
        void IProxyDrawingContext.DrawGeometry(BrushProxy brush, PenProxy pen, Geometry geometry, Geometry clip, Matrix brushTrans, ProxyDrawingFlags flags)
        {
            Debug.Assert(brushTrans.IsIdentity, "brushTrans not supported");

            if ((brush == null) && (pen == null))
            {
                return;
            }

            if (!_costing && (clip != null))
            {
                _dc.PushClip(clip);
            }

            if (brush != null)
            {
                brush = BrushProxy.BlendColorWithBrush(false, Colors.White, brush, false);
            }

            // Simplification, pushing transformation
            if (geometry is LineGeometry)
            {
                LineGeometry line = geometry.CloneCurrentValue() as LineGeometry;

                line.StartPoint = geometry.Transform.Value.Transform(line.StartPoint);
                line.EndPoint   = geometry.Transform.Value.Transform(line.EndPoint);
                line.Transform  = Transform.Identity;
            }

            if ((brush != null) && (brush.BrushList != null)) // List of brushes
            {
                Debug.Assert(pen == null, "no pen");

                if (_costing)
                {
                    FillGeometry(brush.BrushList[0] as BrushProxy, brush.BrushList, 1, geometry);
                }
                else
                {
                    bool rasterize = BetterRasterize(brush, geometry);

                    if (!rasterize)
                    {
                        rasterize = !FillGeometry(brush.BrushList[0] as BrushProxy, brush.BrushList, 1, geometry);
                    }

                    if (rasterize)
                    {
                        bool empty = false;

                        if (clip != null)
                        {
                            // Fix bug 1506957: Clip geometry prior to rasterizing to prevent excessive
                            // rasterization bitmap size.
                            geometry = Utility.Intersect(geometry, clip, Matrix.Identity, out empty);
                        }

                        if (!empty)
                        {
                            RasterizeGeometry(brush, geometry);
                        }
                    }
                }
            }
            else // Single Avalon brush or pen
            {
                Pen        p           = null;
                BrushProxy strokeBrush = null;

                if (pen != null) // Blend pen with White
                {
                    p           = pen.GetPen(true);
                    strokeBrush = pen.StrokeBrush;

                    if (!strokeBrush.IsOpaque())
                    {
                        strokeBrush = BrushProxy.BlendColorWithBrush(false, Colors.White, strokeBrush, false);
                    }
                }

                Brush b = null;

                if (_costing)
                {
                    if (brush != null)
                    {
                        // DrawingBrush is always rasterized onward from this stage.
                        // Avoid the cost of creating new DrawingBrush in GetRealBrush during costing
                        if ((brush.Brush != null) && (brush.Brush is DrawingBrush))
                        {
                            b = brush.Brush;
                        }
                        else
                        {
                            b = brush.GetRealBrush();
                        }
                    }

                    _cost += DrawGeometryCost(b, p, geometry);
                }
                else
                {
                    if (brush != null)
                    {
                        b = brush.GetRealBrush();
                    }

#if DEBUG
                    _seq++;

                    _dc.Comment("-> DrawGeometry " + _seq + ' ' + _comment);
#endif
                    if (p == null)
                    {
                        _dc.DrawGeometry(b, null, null, geometry);
                    }
                    else
                    {
                        _dc.DrawGeometry(b, p, strokeBrush.GetRealBrush(), geometry);
                    }

#if DEBUG
                    _dc.Comment("<- DrawGeometry" + _seq + ' ' + _comment);

                    if (Configuration.Verbose >= 2)
                    {
                        Console.WriteLine("  DrawGeometry(" + _comment + ")");
                    }
#endif
                }
            }

            if (!_costing && (clip != null))
            {
                _dc.PopClip();
            }
        }
Example #4
0
        public void DrawGeometry(Brush brush, Pen pen, Geometry geometry)
        {
            // Ignore total transparent primitive
            if (Utility.IsTransparent(_opacity) || ((brush == null) && (pen == null || pen.Brush == null)) || (geometry == null))
            {
                return;
            }

            // Split if having both pen and brush
            if ((brush != null) && (pen != null))
            // if (!Utility.IsOpaque(_opacity) || (_opacityMask != null))
            {
                // Push a canvas to handle geometry with brush + pen properly
                Push(Matrix.Identity, null, 1.0, null, Rect.Empty, false);

                DrawGeometry(brush, null, geometry);
                DrawGeometry(null, pen, geometry);

                Pop();

                return;
            }

            AssertState(DeviceState.PageStarted, DeviceState.NoChange);

            GeometryPrimitive g = new GeometryPrimitive();

            g.Geometry    = geometry;
            g.Clip        = _clip;
            g.Opacity     = _opacity;
            g.OpacityMask = _opacityMask;

            int needBounds = 0; // 1 for fill, 2 for stroke

            if (brush != null)
            {
                // Fix bug 1427695: Need bounds for non-SolidColorBrushes to enable rebuilding Brush from BrushProxy.
                if (!(brush is SolidColorBrush))
                {
                    needBounds |= 1;
                }
            }

            if ((pen != null) && (pen.Brush != null))
            {
                if (!(pen.Brush is SolidColorBrush))
                {
                    needBounds |= 2;
                }
            }

            if (g.OpacityMask != null)
            {
                if (g.OpacityMask.BrushList == null && !(g.OpacityMask.Brush is SolidColorBrush))
                {
                    if (pen != null)
                    {
                        needBounds |= 2;
                    }
                    else
                    {
                        needBounds |= 1;
                    }
                }
            }

            Rect bounds = g.GetRectBounds((needBounds & 1) != 0);

            if (brush != null)
            {
                g.Brush = BrushProxy.CreateBrush(brush, bounds);
            }

            if ((needBounds & 2) != 0)
            {
                bounds = geometry.GetRenderBounds(pen);
            }

            if ((pen != null) && (pen.Brush != null))
            {
                g.Pen = PenProxy.CreatePen(pen, bounds);
            }

            if (g.OpacityMask != null)
            {
                if (!g.OpacityMask.MakeBrushAbsolute(bounds))
                {
                    // Fix bug 1463955: Brush has become empty; replace with transparent brush.
                    g.OpacityMask = BrushProxy.CreateColorBrush(Colors.Transparent);
                }
            }

            // Optimization: Unfold primitive DrawingBrush when possible to avoid rasterizing it.
            Primitive primitive = g.UnfoldDrawingBrush();

            if (primitive != null)
            {
                _root.Children.Add(primitive);
            }
        }