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