示例#1
0
        bool IProxyDrawingContext.DrawGlyphs(GlyphRun glyphrun, Geometry clip, Matrix trans, BrushProxy foreground)
        {
            Debug.Assert(!_costing, "in costing mode DrawyGlyphs");

            BrushProxy bp = BrushProxy.BlendColorWithBrush(false, Colors.White, foreground, false);

            Brush b = bp.Brush;

            if ((b == null) || (b is DrawingBrush))
            {
                return(false);
            }

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

            if (!trans.IsIdentity)
            {
                _dc.PushTransform(trans);
            }

#if DEBUG
            _seq++;
            _dc.Comment("-> DrawGlyphRun " + _seq);
#endif

            _dc.DrawGlyphRun(b, glyphrun);

#if DEBUG
            _dc.Comment("<- DrawGlyphRun " + _seq);

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

            if (!trans.IsIdentity)
            {
                _dc.PopTransform();
            }

            if (clip != null)
            {
                _dc.PopClip();
            }

            return(true);
        }
示例#2
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();
            }
        }
示例#3
0
        // Breaking RadialGradientBrush apart to simplify drawing
        private bool RadialFillGeometry(BrushProxy radial, BrushProxy other, bool pre, ArrayList brushes, int from, Geometry shape)
        {
            bool opacityOnly      = false;
            RadialGradientBrush b = null;
            double opacity        = 0;

            b = radial.Brush as RadialGradientBrush;

            BrushProxy saveMask    = radial.OpacityMask;
            double     saveOpacity = radial.Opacity;

            if (b != null)
            {
                opacity = radial.Opacity;
            }
            else
            {
                b           = saveMask.Brush as RadialGradientBrush;
                opacity     = saveMask.Opacity;
                opacityOnly = true;

                Debug.Assert(b != null, "RadialGradientBrush expected");
            }

            radial.OpacityMask = null;

            // Need to give flattener BrushProxy's opacity, which includes Brush's opacity and
            // opacity pushed from parent primitives.
            RadialGradientFlattener rf = new RadialGradientFlattener(b, shape, opacity);

            int steps = rf.Steps;

            if (_costing)
            {
                if (steps > Configuration.MaxGradientSteps) // Avoid decomposition if there are too many steps
                {
                    _cost = 1;
                    return(true);
                }
            }
            else
            {
                _dc.PushClip(shape);
            }

            bool result = true;

            for (int i = steps; i > 0; i--)
            {
                Color color;

                Geometry slice = rf.GetSlice(i, out color);

                BrushProxy blend = null;

                if (opacityOnly)
                {
                    radial.Opacity = saveOpacity * Utility.NormalizeOpacity(color.ScA);

                    if (pre)
                    {
                        blend = radial.BlendBrush(other);
                    }
                    else
                    {
                        blend = other.BlendBrush(radial);
                    }
                }
                else
                {
                    if (saveMask == null)
                    {
                        blend = BrushProxy.BlendColorWithBrush(false, color, other, !pre);
                    }
                    else
                    {
                        blend = BrushProxy.BlendColorWithBrush(false, color, saveMask, false);

                        if (pre)
                        {
                            blend = blend.BlendBrush(other);
                        }
                        else
                        {
                            blend = other.BlendBrush(blend);
                        }
                    }
                }

                result = FillGeometry(blend, brushes, from, slice);

                if (!result)
                {
                    break;
                }

                // Break when we already know decomposition of gradient is more costly
                if (_costing && (_cost > 0))
                {
                    break;
                }
            }

            radial.OpacityMask = saveMask;
            radial.Opacity     = saveOpacity;

            if (!_costing)
            {
                _dc.PopClip();
            }

            return(result);
        }